]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/genattrtab.c
b0ebb4623e63c2e1c06b7bd171a5a4cb508d532b
[thirdparty/gcc.git] / gcc / genattrtab.c
1 /* Generate code from machine description to compute values of attributes.
2 Copyright (C) 1991-2015 Free Software Foundation, Inc.
3 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
4
5 This file is part of GCC.
6
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
10 version.
11
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
15 for more details.
16
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/>. */
20
21 /* This program handles insn attributes and the DEFINE_DELAY and
22 DEFINE_INSN_RESERVATION definitions.
23
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.
27
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
32 expression).
33
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.
37
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
45 `get_attr_length'.
46
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
52 used.
53
54 Internal attributes are defined to handle DEFINE_DELAY and
55 DEFINE_INSN_RESERVATION. Special routines are output for these cases.
56
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.
60
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.
65
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.
70
71 The strategy used when processing DEFINE_DELAY definitions is to create
72 arbitrarily complex expressions and have the optimization simplify them.
73
74 Once optimization is complete, any required routines and definitions
75 will be written.
76
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).
84
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
91 (see attr_rtx). */
92
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))
96
97 #if 0
98 #define strcmp_check(S1, S2) ((S1) == (S2) \
99 ? 0 \
100 : (gcc_assert (strcmp ((S1), (S2))), 1))
101 #else
102 #define strcmp_check(S1, S2) ((S1) != (S2))
103 #endif
104
105 #include "bconfig.h"
106 #include "system.h"
107 #include "coretypes.h"
108 #include "tm.h"
109 #include "rtl.h"
110 #include "obstack.h"
111 #include "errors.h"
112 #include "read-md.h"
113 #include "gensupport.h"
114 #include "fnmatch.h"
115
116 #define DEBUG 0
117
118 /* Flags for make_internal_attr's `special' parameter. */
119 #define ATTR_NONE 0
120 #define ATTR_SPECIAL (1 << 0)
121
122 static struct obstack obstack1, obstack2;
123 static struct obstack *hash_obstack = &obstack1;
124 static struct obstack *temp_obstack = &obstack2;
125
126 /* enough space to reserve for printing out ints */
127 #define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3)
128
129 /* Define structures used to record attributes and values. */
130
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. */
135
136 struct insn_def
137 {
138 struct insn_def *next; /* Next insn in chain. */
139 rtx def; /* The DEFINE_... */
140 int insn_code; /* Instruction number. */
141 int insn_index; /* Expression number in file, for errors. */
142 file_location loc; /* Where in the .md files it occurs. */
143 int num_alternatives; /* Number of alternatives. */
144 int vec_idx; /* Index of attribute vector in `def'. */
145 };
146
147 /* Once everything has been read in, we store in each attribute value a list
148 of insn codes that have that value. Here is the structure used for the
149 list. */
150
151 struct insn_ent
152 {
153 struct insn_ent *next; /* Next in chain. */
154 struct insn_def *def; /* Instruction definition. */
155 };
156
157 /* Each value of an attribute (either constant or computed) is assigned a
158 structure which is used as the listhead of the insns that have that
159 value. */
160
161 struct attr_value
162 {
163 rtx value; /* Value of attribute. */
164 struct attr_value *next; /* Next attribute value in chain. */
165 struct insn_ent *first_insn; /* First insn with this value. */
166 int num_insns; /* Number of insns with this value. */
167 int has_asm_insn; /* True if this value used for `asm' insns */
168 };
169
170 /* Structure for each attribute. */
171
172 struct attr_desc
173 {
174 char *name; /* Name of attribute. */
175 const char *enum_name; /* Enum name for DEFINE_ENUM_NAME. */
176 struct attr_desc *next; /* Next attribute. */
177 struct attr_value *first_value; /* First value of this attribute. */
178 struct attr_value *default_val; /* Default value for this attribute. */
179 file_location loc; /* Where in the .md files it occurs. */
180 unsigned is_numeric : 1; /* Values of this attribute are numeric. */
181 unsigned is_const : 1; /* Attribute value constant for each run. */
182 unsigned is_special : 1; /* Don't call `write_attr_set'. */
183 };
184
185 /* Structure for each DEFINE_DELAY. */
186
187 struct delay_desc
188 {
189 rtx def; /* DEFINE_DELAY expression. */
190 struct delay_desc *next; /* Next DEFINE_DELAY. */
191 file_location loc; /* Where in the .md files it occurs. */
192 int num; /* Number of DEFINE_DELAY, starting at 1. */
193 };
194
195 struct attr_value_list
196 {
197 struct attr_value *av;
198 struct insn_ent *ie;
199 struct attr_desc *attr;
200 struct attr_value_list *next;
201 };
202
203 /* Listheads of above structures. */
204
205 /* This one is indexed by the first character of the attribute name. */
206 #define MAX_ATTRS_INDEX 256
207 static struct attr_desc *attrs[MAX_ATTRS_INDEX];
208 static struct insn_def *defs;
209 static struct delay_desc *delays;
210 struct attr_value_list **insn_code_values;
211
212 /* Other variables. */
213
214 static int insn_code_number;
215 static int insn_index_number;
216 static int got_define_asm_attributes;
217 static int must_extract;
218 static int must_constrain;
219 static int address_used;
220 static int length_used;
221 static int num_delays;
222 static int have_annul_true, have_annul_false;
223 static int num_insn_ents;
224
225 /* Stores, for each insn code, the number of constraint alternatives. */
226
227 static int *insn_n_alternatives;
228
229 /* Stores, for each insn code, a bitmap that has bits on for each possible
230 alternative. */
231
232 static uint64_t *insn_alternatives;
233
234 /* Used to simplify expressions. */
235
236 static rtx true_rtx, false_rtx;
237
238 /* Used to reduce calls to `strcmp' */
239
240 static const char *alternative_name;
241 static const char *length_str;
242 static const char *delay_type_str;
243 static const char *delay_1_0_str;
244 static const char *num_delay_slots_str;
245
246 /* Simplify an expression. Only call the routine if there is something to
247 simplify. */
248 #define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX) \
249 (ATTR_IND_SIMPLIFIED_P (EXP) || ATTR_CURR_SIMPLIFIED_P (EXP) ? (EXP) \
250 : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
251
252 #define DEF_ATTR_STRING(S) (attr_string ((S), strlen (S)))
253
254 /* Forward declarations of functions used before their definitions, only. */
255 static char *attr_string (const char *, int);
256 static char *attr_printf (unsigned int, const char *, ...)
257 ATTRIBUTE_PRINTF_2;
258 static rtx make_numeric_value (int);
259 static struct attr_desc *find_attr (const char **, int);
260 static rtx mk_attr_alt (uint64_t);
261 static char *next_comma_elt (const char **);
262 static rtx insert_right_side (enum rtx_code, rtx, rtx, int, int);
263 static rtx copy_boolean (rtx);
264 static int compares_alternatives_p (rtx);
265 static void make_internal_attr (const char *, rtx, int);
266 static void insert_insn_ent (struct attr_value *, struct insn_ent *);
267 static void walk_attr_value (rtx);
268 static int max_attr_value (rtx, int*);
269 static int min_attr_value (rtx, int*);
270 static int or_attr_value (rtx, int*);
271 static rtx simplify_test_exp (rtx, int, int);
272 static rtx simplify_test_exp_in_temp (rtx, int, int);
273 static rtx copy_rtx_unchanging (rtx);
274 static bool attr_alt_subset_p (rtx, rtx);
275 static bool attr_alt_subset_of_compl_p (rtx, rtx);
276 static void clear_struct_flag (rtx);
277 static void write_attr_valueq (FILE *, struct attr_desc *, const char *);
278 static struct attr_value *find_most_used (struct attr_desc *);
279 static void write_attr_set (FILE *, struct attr_desc *, int, rtx,
280 const char *, const char *, rtx,
281 int, int, unsigned int);
282 static void write_attr_case (FILE *, struct attr_desc *,
283 struct attr_value *,
284 int, const char *, const char *, int, rtx);
285 static void write_attr_value (FILE *, struct attr_desc *, rtx);
286 static void write_upcase (FILE *, const char *);
287 static void write_indent (FILE *, int);
288 static rtx identity_fn (rtx);
289 static rtx zero_fn (rtx);
290 static rtx one_fn (rtx);
291 static rtx max_fn (rtx);
292 static rtx min_fn (rtx);
293
294 #define oballoc(T) XOBNEW (hash_obstack, T)
295 #define oballocvec(T, N) XOBNEWVEC (hash_obstack, T, (N))
296
297 /* This gen* file is unique, in that it writes out multiple files.
298
299 Before GCC 4.8, insn-attrtab.c was written out containing many large
300 functions and tables. This made insn-attrtab.c _the_ bottle-neck in
301 a parallel build, and even made it impossible to build GCC on machines
302 with relatively small RAM space (PR other/29442). Therefore, the
303 atrribute functions/tables are now written out to three separate
304 files: all "*insn_default_latency" functions go to LATENCY_FILE_NAME,
305 all "*internal_dfa_insn_code" functions go to DFA_FILE_NAME, and the
306 rest goes to ATTR_FILE_NAME. */
307
308 static const char *attr_file_name = NULL;
309 static const char *dfa_file_name = NULL;
310 static const char *latency_file_name = NULL;
311
312 static FILE *attr_file, *dfa_file, *latency_file;
313
314 /* Hash table for sharing RTL and strings. */
315
316 /* Each hash table slot is a bucket containing a chain of these structures.
317 Strings are given negative hash codes; RTL expressions are given positive
318 hash codes. */
319
320 struct attr_hash
321 {
322 struct attr_hash *next; /* Next structure in the bucket. */
323 unsigned int hashcode; /* Hash code of this rtx or string. */
324 union
325 {
326 char *str; /* The string (negative hash codes) */
327 rtx rtl; /* or the RTL recorded here. */
328 } u;
329 };
330
331 /* Now here is the hash table. When recording an RTL, it is added to
332 the slot whose index is the hash code mod the table size. Note
333 that the hash table is used for several kinds of RTL (see attr_rtx)
334 and for strings. While all these live in the same table, they are
335 completely independent, and the hash code is computed differently
336 for each. */
337
338 #define RTL_HASH_SIZE 4093
339 static struct attr_hash *attr_hash_table[RTL_HASH_SIZE];
340
341 /* Here is how primitive or already-shared RTL's hash
342 codes are made. */
343 #define RTL_HASH(RTL) ((intptr_t) (RTL) & 0777777)
344
345 /* Add an entry to the hash table for RTL with hash code HASHCODE. */
346
347 static void
348 attr_hash_add_rtx (unsigned int hashcode, rtx rtl)
349 {
350 struct attr_hash *h;
351
352 h = XOBNEW (hash_obstack, struct attr_hash);
353 h->hashcode = hashcode;
354 h->u.rtl = rtl;
355 h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
356 attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
357 }
358
359 /* Add an entry to the hash table for STRING with hash code HASHCODE. */
360
361 static void
362 attr_hash_add_string (unsigned int hashcode, char *str)
363 {
364 struct attr_hash *h;
365
366 h = XOBNEW (hash_obstack, struct attr_hash);
367 h->hashcode = -hashcode;
368 h->u.str = str;
369 h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
370 attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
371 }
372
373 /* Generate an RTL expression, but avoid duplicates.
374 Set the ATTR_PERMANENT_P flag for these permanent objects.
375
376 In some cases we cannot uniquify; then we return an ordinary
377 impermanent rtx with ATTR_PERMANENT_P clear.
378
379 Args are as follows:
380
381 rtx attr_rtx (code, [element1, ..., elementn]) */
382
383 static rtx
384 attr_rtx_1 (enum rtx_code code, va_list p)
385 {
386 rtx rt_val = NULL_RTX;/* RTX to return to caller... */
387 unsigned int hashcode;
388 struct attr_hash *h;
389 struct obstack *old_obstack = rtl_obstack;
390
391 /* For each of several cases, search the hash table for an existing entry.
392 Use that entry if one is found; otherwise create a new RTL and add it
393 to the table. */
394
395 if (GET_RTX_CLASS (code) == RTX_UNARY)
396 {
397 rtx arg0 = va_arg (p, rtx);
398
399 /* A permanent object cannot point to impermanent ones. */
400 if (! ATTR_PERMANENT_P (arg0))
401 {
402 rt_val = rtx_alloc (code);
403 XEXP (rt_val, 0) = arg0;
404 return rt_val;
405 }
406
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)
412 return h->u.rtl;
413
414 if (h == 0)
415 {
416 rtl_obstack = hash_obstack;
417 rt_val = rtx_alloc (code);
418 XEXP (rt_val, 0) = arg0;
419 }
420 }
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)
425 {
426 rtx arg0 = va_arg (p, rtx);
427 rtx arg1 = va_arg (p, rtx);
428
429 /* A permanent object cannot point to impermanent ones. */
430 if (! ATTR_PERMANENT_P (arg0) || ! ATTR_PERMANENT_P (arg1))
431 {
432 rt_val = rtx_alloc (code);
433 XEXP (rt_val, 0) = arg0;
434 XEXP (rt_val, 1) = arg1;
435 return rt_val;
436 }
437
438 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
439 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
440 if (h->hashcode == hashcode
441 && GET_CODE (h->u.rtl) == code
442 && XEXP (h->u.rtl, 0) == arg0
443 && XEXP (h->u.rtl, 1) == arg1)
444 return h->u.rtl;
445
446 if (h == 0)
447 {
448 rtl_obstack = hash_obstack;
449 rt_val = rtx_alloc (code);
450 XEXP (rt_val, 0) = arg0;
451 XEXP (rt_val, 1) = arg1;
452 }
453 }
454 else if (code == SYMBOL_REF
455 || (GET_RTX_LENGTH (code) == 1
456 && GET_RTX_FORMAT (code)[0] == 's'))
457 {
458 char *arg0 = va_arg (p, char *);
459
460 arg0 = DEF_ATTR_STRING (arg0);
461
462 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
463 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
464 if (h->hashcode == hashcode
465 && GET_CODE (h->u.rtl) == code
466 && XSTR (h->u.rtl, 0) == arg0)
467 return h->u.rtl;
468
469 if (h == 0)
470 {
471 rtl_obstack = hash_obstack;
472 rt_val = rtx_alloc (code);
473 XSTR (rt_val, 0) = arg0;
474 if (code == SYMBOL_REF)
475 X0EXP (rt_val, 1) = NULL_RTX;
476 }
477 }
478 else if (GET_RTX_LENGTH (code) == 2
479 && GET_RTX_FORMAT (code)[0] == 's'
480 && GET_RTX_FORMAT (code)[1] == 's')
481 {
482 char *arg0 = va_arg (p, char *);
483 char *arg1 = va_arg (p, char *);
484
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)
491 return h->u.rtl;
492
493 if (h == 0)
494 {
495 rtl_obstack = hash_obstack;
496 rt_val = rtx_alloc (code);
497 XSTR (rt_val, 0) = arg0;
498 XSTR (rt_val, 1) = arg1;
499 }
500 }
501 else if (code == CONST_INT)
502 {
503 HOST_WIDE_INT arg0 = va_arg (p, HOST_WIDE_INT);
504 if (arg0 == 0)
505 return false_rtx;
506 else if (arg0 == 1)
507 return true_rtx;
508 else
509 goto nohash;
510 }
511 else
512 {
513 int i; /* Array indices... */
514 const char *fmt; /* Current rtx's format... */
515 nohash:
516 rt_val = rtx_alloc (code); /* Allocate the storage space. */
517
518 fmt = GET_RTX_FORMAT (code); /* Find the right format... */
519 for (i = 0; i < GET_RTX_LENGTH (code); i++)
520 {
521 switch (*fmt++)
522 {
523 case '0': /* Unused field. */
524 break;
525
526 case 'i': /* An integer? */
527 XINT (rt_val, i) = va_arg (p, int);
528 break;
529
530 case 'w': /* A wide integer? */
531 XWINT (rt_val, i) = va_arg (p, HOST_WIDE_INT);
532 break;
533
534 case 's': /* A string? */
535 XSTR (rt_val, i) = va_arg (p, char *);
536 break;
537
538 case 'e': /* An expression? */
539 case 'u': /* An insn? Same except when printing. */
540 XEXP (rt_val, i) = va_arg (p, rtx);
541 break;
542
543 case 'E': /* An RTX vector? */
544 XVEC (rt_val, i) = va_arg (p, rtvec);
545 break;
546
547 default:
548 gcc_unreachable ();
549 }
550 }
551 return rt_val;
552 }
553
554 rtl_obstack = old_obstack;
555 attr_hash_add_rtx (hashcode, rt_val);
556 ATTR_PERMANENT_P (rt_val) = 1;
557 return rt_val;
558 }
559
560 static rtx
561 attr_rtx (enum rtx_code code, ...)
562 {
563 rtx result;
564 va_list p;
565
566 va_start (p, code);
567 result = attr_rtx_1 (code, p);
568 va_end (p);
569 return result;
570 }
571
572 /* Create a new string printed with the printf line arguments into a space
573 of at most LEN bytes:
574
575 rtx attr_printf (len, format, [arg1, ..., argn]) */
576
577 static char *
578 attr_printf (unsigned int len, const char *fmt, ...)
579 {
580 char str[256];
581 va_list p;
582
583 va_start (p, fmt);
584
585 gcc_assert (len < sizeof str); /* Leave room for \0. */
586
587 vsprintf (str, fmt, p);
588 va_end (p);
589
590 return DEF_ATTR_STRING (str);
591 }
592
593 static rtx
594 attr_eq (const char *name, const char *value)
595 {
596 return attr_rtx (EQ_ATTR, DEF_ATTR_STRING (name), DEF_ATTR_STRING (value));
597 }
598
599 static const char *
600 attr_numeral (int n)
601 {
602 return XSTR (make_numeric_value (n), 0);
603 }
604
605 /* Return a permanent (possibly shared) copy of a string STR (not assumed
606 to be null terminated) with LEN bytes. */
607
608 static char *
609 attr_string (const char *str, int len)
610 {
611 struct attr_hash *h;
612 unsigned int hashcode;
613 int i;
614 char *new_str;
615
616 /* Compute the hash code. */
617 hashcode = (len + 1) * 613U + (unsigned) str[0];
618 for (i = 1; i < len; i += 2)
619 hashcode = ((hashcode * 613) + (unsigned) str[i]);
620 if ((int) hashcode < 0)
621 hashcode = -hashcode;
622
623 /* Search the table for the string. */
624 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
625 if (h->hashcode == -hashcode && h->u.str[0] == str[0]
626 && !strncmp (h->u.str, str, len))
627 return h->u.str; /* <-- return if found. */
628
629 /* Not found; create a permanent copy and add it to the hash table. */
630 new_str = XOBNEWVAR (hash_obstack, char, len + 1);
631 memcpy (new_str, str, len);
632 new_str[len] = '\0';
633 attr_hash_add_string (hashcode, new_str);
634 copy_md_ptr_loc (new_str, str);
635
636 return new_str; /* Return the new string. */
637 }
638
639 /* Check two rtx's for equality of contents,
640 taking advantage of the fact that if both are hashed
641 then they can't be equal unless they are the same object. */
642
643 static int
644 attr_equal_p (rtx x, rtx y)
645 {
646 return (x == y || (! (ATTR_PERMANENT_P (x) && ATTR_PERMANENT_P (y))
647 && rtx_equal_p (x, y)));
648 }
649
650 /* Copy an attribute value expression,
651 descending to all depths, but not copying any
652 permanent hashed subexpressions. */
653
654 static rtx
655 attr_copy_rtx (rtx orig)
656 {
657 rtx copy;
658 int i, j;
659 RTX_CODE code;
660 const char *format_ptr;
661
662 /* No need to copy a permanent object. */
663 if (ATTR_PERMANENT_P (orig))
664 return orig;
665
666 code = GET_CODE (orig);
667
668 switch (code)
669 {
670 case REG:
671 CASE_CONST_ANY:
672 case SYMBOL_REF:
673 case MATCH_TEST:
674 case CODE_LABEL:
675 case PC:
676 case CC0:
677 return orig;
678
679 default:
680 break;
681 }
682
683 copy = rtx_alloc (code);
684 PUT_MODE (copy, GET_MODE (orig));
685 ATTR_IND_SIMPLIFIED_P (copy) = ATTR_IND_SIMPLIFIED_P (orig);
686 ATTR_CURR_SIMPLIFIED_P (copy) = ATTR_CURR_SIMPLIFIED_P (orig);
687 ATTR_PERMANENT_P (copy) = ATTR_PERMANENT_P (orig);
688
689 format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
690
691 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
692 {
693 switch (*format_ptr++)
694 {
695 case 'e':
696 XEXP (copy, i) = XEXP (orig, i);
697 if (XEXP (orig, i) != NULL)
698 XEXP (copy, i) = attr_copy_rtx (XEXP (orig, i));
699 break;
700
701 case 'E':
702 case 'V':
703 XVEC (copy, i) = XVEC (orig, i);
704 if (XVEC (orig, i) != NULL)
705 {
706 XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
707 for (j = 0; j < XVECLEN (copy, i); j++)
708 XVECEXP (copy, i, j) = attr_copy_rtx (XVECEXP (orig, i, j));
709 }
710 break;
711
712 case 'n':
713 case 'i':
714 XINT (copy, i) = XINT (orig, i);
715 break;
716
717 case 'w':
718 XWINT (copy, i) = XWINT (orig, i);
719 break;
720
721 case 's':
722 case 'S':
723 XSTR (copy, i) = XSTR (orig, i);
724 break;
725
726 default:
727 gcc_unreachable ();
728 }
729 }
730 return copy;
731 }
732
733 /* Given a test expression for an attribute, ensure it is validly formed.
734 IS_CONST indicates whether the expression is constant for each compiler
735 run (a constant expression may not test any particular insn).
736
737 Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
738 and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
739 test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
740
741 Update the string address in EQ_ATTR expression to be the same used
742 in the attribute (or `alternative_name') to speed up subsequent
743 `find_attr' calls and eliminate most `strcmp' calls.
744
745 Return the new expression, if any. */
746
747 static rtx
748 check_attr_test (rtx exp, int is_const, file_location loc)
749 {
750 struct attr_desc *attr;
751 struct attr_value *av;
752 const char *name_ptr, *p;
753 rtx orexp, newexp;
754
755 switch (GET_CODE (exp))
756 {
757 case EQ_ATTR:
758 /* Handle negation test. */
759 if (XSTR (exp, 1)[0] == '!')
760 return check_attr_test (attr_rtx (NOT,
761 attr_eq (XSTR (exp, 0),
762 &XSTR (exp, 1)[1])),
763 is_const, loc);
764
765 else if (n_comma_elts (XSTR (exp, 1)) == 1)
766 {
767 attr = find_attr (&XSTR (exp, 0), 0);
768 if (attr == NULL)
769 {
770 if (! strcmp (XSTR (exp, 0), "alternative"))
771 return mk_attr_alt (((uint64_t) 1) << atoi (XSTR (exp, 1)));
772 else
773 fatal_at (loc, "unknown attribute `%s' in EQ_ATTR",
774 XSTR (exp, 0));
775 }
776
777 if (is_const && ! attr->is_const)
778 fatal_at (loc, "constant expression uses insn attribute `%s'"
779 " in EQ_ATTR", XSTR (exp, 0));
780
781 /* Copy this just to make it permanent,
782 so expressions using it can be permanent too. */
783 exp = attr_eq (XSTR (exp, 0), XSTR (exp, 1));
784
785 /* It shouldn't be possible to simplify the value given to a
786 constant attribute, so don't expand this until it's time to
787 write the test expression. */
788 if (attr->is_const)
789 ATTR_IND_SIMPLIFIED_P (exp) = 1;
790
791 if (attr->is_numeric)
792 {
793 for (p = XSTR (exp, 1); *p; p++)
794 if (! ISDIGIT (*p))
795 fatal_at (loc, "attribute `%s' takes only numeric values",
796 XSTR (exp, 0));
797 }
798 else
799 {
800 for (av = attr->first_value; av; av = av->next)
801 if (GET_CODE (av->value) == CONST_STRING
802 && ! strcmp (XSTR (exp, 1), XSTR (av->value, 0)))
803 break;
804
805 if (av == NULL)
806 fatal_at (loc, "unknown value `%s' for `%s' attribute",
807 XSTR (exp, 1), XSTR (exp, 0));
808 }
809 }
810 else
811 {
812 if (! strcmp (XSTR (exp, 0), "alternative"))
813 {
814 int set = 0;
815
816 name_ptr = XSTR (exp, 1);
817 while ((p = next_comma_elt (&name_ptr)) != NULL)
818 set |= ((uint64_t) 1) << atoi (p);
819
820 return mk_attr_alt (set);
821 }
822 else
823 {
824 /* Make an IOR tree of the possible values. */
825 orexp = false_rtx;
826 name_ptr = XSTR (exp, 1);
827 while ((p = next_comma_elt (&name_ptr)) != NULL)
828 {
829 newexp = attr_eq (XSTR (exp, 0), p);
830 orexp = insert_right_side (IOR, orexp, newexp, -2, -2);
831 }
832
833 return check_attr_test (orexp, is_const, loc);
834 }
835 }
836 break;
837
838 case ATTR_FLAG:
839 break;
840
841 case CONST_INT:
842 /* Either TRUE or FALSE. */
843 if (XWINT (exp, 0))
844 return true_rtx;
845 else
846 return false_rtx;
847
848 case IOR:
849 case AND:
850 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const, loc);
851 XEXP (exp, 1) = check_attr_test (XEXP (exp, 1), is_const, loc);
852 break;
853
854 case NOT:
855 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const, loc);
856 break;
857
858 case MATCH_TEST:
859 exp = attr_rtx (MATCH_TEST, XSTR (exp, 0));
860 ATTR_IND_SIMPLIFIED_P (exp) = 1;
861 break;
862
863 case MATCH_OPERAND:
864 if (is_const)
865 fatal_at (loc, "RTL operator \"%s\" not valid in constant attribute"
866 " test", GET_RTX_NAME (GET_CODE (exp)));
867 /* These cases can't be simplified. */
868 ATTR_IND_SIMPLIFIED_P (exp) = 1;
869 break;
870
871 case LE: case LT: case GT: case GE:
872 case LEU: case LTU: case GTU: case GEU:
873 case NE: case EQ:
874 if (GET_CODE (XEXP (exp, 0)) == SYMBOL_REF
875 && GET_CODE (XEXP (exp, 1)) == SYMBOL_REF)
876 exp = attr_rtx (GET_CODE (exp),
877 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 0), 0)),
878 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 1), 0)));
879 /* These cases can't be simplified. */
880 ATTR_IND_SIMPLIFIED_P (exp) = 1;
881 break;
882
883 case SYMBOL_REF:
884 if (is_const)
885 {
886 /* These cases are valid for constant attributes, but can't be
887 simplified. */
888 exp = attr_rtx (SYMBOL_REF, XSTR (exp, 0));
889 ATTR_IND_SIMPLIFIED_P (exp) = 1;
890 break;
891 }
892 default:
893 fatal_at (loc, "RTL operator \"%s\" not valid in attribute test",
894 GET_RTX_NAME (GET_CODE (exp)));
895 }
896
897 return exp;
898 }
899
900 /* Given an expression, ensure that it is validly formed and that all named
901 attribute values are valid for the given attribute. Issue a fatal error
902 if not.
903
904 Return a perhaps modified replacement expression for the value. */
905
906 static rtx
907 check_attr_value (rtx exp, struct attr_desc *attr)
908 {
909 struct attr_value *av;
910 const char *p;
911 int i;
912
913 switch (GET_CODE (exp))
914 {
915 case CONST_INT:
916 if (!attr->is_numeric)
917 {
918 error_at (attr->loc,
919 "CONST_INT not valid for non-numeric attribute %s",
920 attr->name);
921 break;
922 }
923
924 if (INTVAL (exp) < 0)
925 {
926 error_at (attr->loc,
927 "negative numeric value specified for attribute %s",
928 attr->name);
929 break;
930 }
931 break;
932
933 case CONST_STRING:
934 if (! strcmp (XSTR (exp, 0), "*"))
935 break;
936
937 if (attr->is_numeric)
938 {
939 p = XSTR (exp, 0);
940 for (; *p; p++)
941 if (! ISDIGIT (*p))
942 {
943 error_at (attr->loc,
944 "non-numeric value for numeric attribute %s",
945 attr->name);
946 break;
947 }
948 break;
949 }
950
951 for (av = attr->first_value; av; av = av->next)
952 if (GET_CODE (av->value) == CONST_STRING
953 && ! strcmp (XSTR (av->value, 0), XSTR (exp, 0)))
954 break;
955
956 if (av == NULL)
957 error_at (attr->loc, "unknown value `%s' for `%s' attribute",
958 XSTR (exp, 0), attr->name);
959 break;
960
961 case IF_THEN_ELSE:
962 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), attr->is_const,
963 attr->loc);
964 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
965 XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
966 break;
967
968 case PLUS:
969 case MINUS:
970 case MULT:
971 case DIV:
972 case MOD:
973 if (!attr->is_numeric)
974 {
975 error_at (attr->loc, "invalid operation `%s' for non-numeric"
976 " attribute value", GET_RTX_NAME (GET_CODE (exp)));
977 break;
978 }
979 /* Fall through. */
980
981 case IOR:
982 case AND:
983 XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
984 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
985 break;
986
987 case FFS:
988 case CLZ:
989 case CTZ:
990 case POPCOUNT:
991 case PARITY:
992 case BSWAP:
993 XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
994 break;
995
996 case COND:
997 if (XVECLEN (exp, 0) % 2 != 0)
998 {
999 error_at (attr->loc, "first operand of COND must have even length");
1000 break;
1001 }
1002
1003 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1004 {
1005 XVECEXP (exp, 0, i) = check_attr_test (XVECEXP (exp, 0, i),
1006 attr->is_const, attr->loc);
1007 XVECEXP (exp, 0, i + 1)
1008 = check_attr_value (XVECEXP (exp, 0, i + 1), attr);
1009 }
1010
1011 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1012 break;
1013
1014 case ATTR:
1015 {
1016 struct attr_desc *attr2 = find_attr (&XSTR (exp, 0), 0);
1017 if (attr2 == NULL)
1018 error_at (attr->loc, "unknown attribute `%s' in ATTR",
1019 XSTR (exp, 0));
1020 else if (attr->is_const && ! attr2->is_const)
1021 error_at (attr->loc,
1022 "non-constant attribute `%s' referenced from `%s'",
1023 XSTR (exp, 0), attr->name);
1024 else if (attr->is_numeric != attr2->is_numeric)
1025 error_at (attr->loc,
1026 "numeric attribute mismatch calling `%s' from `%s'",
1027 XSTR (exp, 0), attr->name);
1028 }
1029 break;
1030
1031 case SYMBOL_REF:
1032 /* A constant SYMBOL_REF is valid as a constant attribute test and
1033 is expanded later by make_canonical into a COND. In a non-constant
1034 attribute test, it is left be. */
1035 return attr_rtx (SYMBOL_REF, XSTR (exp, 0));
1036
1037 default:
1038 error_at (attr->loc, "invalid operation `%s' for attribute value",
1039 GET_RTX_NAME (GET_CODE (exp)));
1040 break;
1041 }
1042
1043 return exp;
1044 }
1045
1046 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
1047 It becomes a COND with each test being (eq_attr "alternative" "n") */
1048
1049 static rtx
1050 convert_set_attr_alternative (rtx exp, struct insn_def *id)
1051 {
1052 int num_alt = id->num_alternatives;
1053 rtx condexp;
1054 int i;
1055
1056 if (XVECLEN (exp, 1) != num_alt)
1057 {
1058 error_at (id->loc, "bad number of entries in SET_ATTR_ALTERNATIVE,"
1059 " was %d expected %d", XVECLEN (exp, 1), num_alt);
1060 return NULL_RTX;
1061 }
1062
1063 /* Make a COND with all tests but the last. Select the last value via the
1064 default. */
1065 condexp = rtx_alloc (COND);
1066 XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);
1067
1068 for (i = 0; i < num_alt - 1; i++)
1069 {
1070 const char *p;
1071 p = attr_numeral (i);
1072
1073 XVECEXP (condexp, 0, 2 * i) = attr_eq (alternative_name, p);
1074 XVECEXP (condexp, 0, 2 * i + 1) = XVECEXP (exp, 1, i);
1075 }
1076
1077 XEXP (condexp, 1) = XVECEXP (exp, 1, i);
1078
1079 return attr_rtx (SET, attr_rtx (ATTR, XSTR (exp, 0)), condexp);
1080 }
1081
1082 /* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
1083 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
1084
1085 static rtx
1086 convert_set_attr (rtx exp, struct insn_def *id)
1087 {
1088 rtx newexp;
1089 const char *name_ptr;
1090 char *p;
1091 int n;
1092
1093 /* See how many alternative specified. */
1094 n = n_comma_elts (XSTR (exp, 1));
1095 if (n == 1)
1096 return attr_rtx (SET,
1097 attr_rtx (ATTR, XSTR (exp, 0)),
1098 attr_rtx (CONST_STRING, XSTR (exp, 1)));
1099
1100 newexp = rtx_alloc (SET_ATTR_ALTERNATIVE);
1101 XSTR (newexp, 0) = XSTR (exp, 0);
1102 XVEC (newexp, 1) = rtvec_alloc (n);
1103
1104 /* Process each comma-separated name. */
1105 name_ptr = XSTR (exp, 1);
1106 n = 0;
1107 while ((p = next_comma_elt (&name_ptr)) != NULL)
1108 XVECEXP (newexp, 1, n++) = attr_rtx (CONST_STRING, p);
1109
1110 return convert_set_attr_alternative (newexp, id);
1111 }
1112
1113 /* Scan all definitions, checking for validity. Also, convert any SET_ATTR
1114 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
1115 expressions. */
1116
1117 static void
1118 check_defs (void)
1119 {
1120 struct insn_def *id;
1121 struct attr_desc *attr;
1122 int i;
1123 rtx value;
1124
1125 for (id = defs; id; id = id->next)
1126 {
1127 if (XVEC (id->def, id->vec_idx) == NULL)
1128 continue;
1129
1130 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1131 {
1132 value = XVECEXP (id->def, id->vec_idx, i);
1133 switch (GET_CODE (value))
1134 {
1135 case SET:
1136 if (GET_CODE (XEXP (value, 0)) != ATTR)
1137 {
1138 error_at (id->loc, "bad attribute set");
1139 value = NULL_RTX;
1140 }
1141 break;
1142
1143 case SET_ATTR_ALTERNATIVE:
1144 value = convert_set_attr_alternative (value, id);
1145 break;
1146
1147 case SET_ATTR:
1148 value = convert_set_attr (value, id);
1149 break;
1150
1151 default:
1152 error_at (id->loc, "invalid attribute code %s",
1153 GET_RTX_NAME (GET_CODE (value)));
1154 value = NULL_RTX;
1155 }
1156 if (value == NULL_RTX)
1157 continue;
1158
1159 if ((attr = find_attr (&XSTR (XEXP (value, 0), 0), 0)) == NULL)
1160 {
1161 error_at (id->loc, "unknown attribute %s",
1162 XSTR (XEXP (value, 0), 0));
1163 continue;
1164 }
1165
1166 XVECEXP (id->def, id->vec_idx, i) = value;
1167 XEXP (value, 1) = check_attr_value (XEXP (value, 1), attr);
1168 }
1169 }
1170 }
1171
1172 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1173 expressions by converting them into a COND. This removes cases from this
1174 program. Also, replace an attribute value of "*" with the default attribute
1175 value. */
1176
1177 static rtx
1178 make_canonical (struct attr_desc *attr, rtx exp)
1179 {
1180 int i;
1181 rtx newexp;
1182
1183 switch (GET_CODE (exp))
1184 {
1185 case CONST_INT:
1186 exp = make_numeric_value (INTVAL (exp));
1187 break;
1188
1189 case CONST_STRING:
1190 if (! strcmp (XSTR (exp, 0), "*"))
1191 {
1192 if (attr->default_val == 0)
1193 fatal ("(attr_value \"*\") used in invalid context");
1194 exp = attr->default_val->value;
1195 }
1196 else
1197 XSTR (exp, 0) = DEF_ATTR_STRING (XSTR (exp, 0));
1198
1199 break;
1200
1201 case SYMBOL_REF:
1202 if (!attr->is_const || ATTR_IND_SIMPLIFIED_P (exp))
1203 break;
1204 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1205 This makes the COND something that won't be considered an arbitrary
1206 expression by walk_attr_value. */
1207 ATTR_IND_SIMPLIFIED_P (exp) = 1;
1208 exp = check_attr_value (exp, attr);
1209 break;
1210
1211 case IF_THEN_ELSE:
1212 newexp = rtx_alloc (COND);
1213 XVEC (newexp, 0) = rtvec_alloc (2);
1214 XVECEXP (newexp, 0, 0) = XEXP (exp, 0);
1215 XVECEXP (newexp, 0, 1) = XEXP (exp, 1);
1216
1217 XEXP (newexp, 1) = XEXP (exp, 2);
1218
1219 exp = newexp;
1220 /* Fall through to COND case since this is now a COND. */
1221
1222 case COND:
1223 {
1224 int allsame = 1;
1225 rtx defval;
1226
1227 /* First, check for degenerate COND. */
1228 if (XVECLEN (exp, 0) == 0)
1229 return make_canonical (attr, XEXP (exp, 1));
1230 defval = XEXP (exp, 1) = make_canonical (attr, XEXP (exp, 1));
1231
1232 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1233 {
1234 XVECEXP (exp, 0, i) = copy_boolean (XVECEXP (exp, 0, i));
1235 XVECEXP (exp, 0, i + 1)
1236 = make_canonical (attr, XVECEXP (exp, 0, i + 1));
1237 if (! rtx_equal_p (XVECEXP (exp, 0, i + 1), defval))
1238 allsame = 0;
1239 }
1240 if (allsame)
1241 return defval;
1242 }
1243 break;
1244
1245 default:
1246 break;
1247 }
1248
1249 return exp;
1250 }
1251
1252 static rtx
1253 copy_boolean (rtx exp)
1254 {
1255 if (GET_CODE (exp) == AND || GET_CODE (exp) == IOR)
1256 return attr_rtx (GET_CODE (exp), copy_boolean (XEXP (exp, 0)),
1257 copy_boolean (XEXP (exp, 1)));
1258 if (GET_CODE (exp) == MATCH_OPERAND)
1259 {
1260 XSTR (exp, 1) = DEF_ATTR_STRING (XSTR (exp, 1));
1261 XSTR (exp, 2) = DEF_ATTR_STRING (XSTR (exp, 2));
1262 }
1263 else if (GET_CODE (exp) == EQ_ATTR)
1264 {
1265 XSTR (exp, 0) = DEF_ATTR_STRING (XSTR (exp, 0));
1266 XSTR (exp, 1) = DEF_ATTR_STRING (XSTR (exp, 1));
1267 }
1268
1269 return exp;
1270 }
1271
1272 /* Given a value and an attribute description, return a `struct attr_value *'
1273 that represents that value. This is either an existing structure, if the
1274 value has been previously encountered, or a newly-created structure.
1275
1276 `insn_code' is the code of an insn whose attribute has the specified
1277 value (-2 if not processing an insn). We ensure that all insns for
1278 a given value have the same number of alternatives if the value checks
1279 alternatives. */
1280
1281 static struct attr_value *
1282 get_attr_value (rtx value, struct attr_desc *attr, int insn_code)
1283 {
1284 struct attr_value *av;
1285 uint64_t num_alt = 0;
1286
1287 value = make_canonical (attr, value);
1288 if (compares_alternatives_p (value))
1289 {
1290 if (insn_code < 0 || insn_alternatives == NULL)
1291 fatal ("(eq_attr \"alternatives\" ...) used in non-insn context");
1292 else
1293 num_alt = insn_alternatives[insn_code];
1294 }
1295
1296 for (av = attr->first_value; av; av = av->next)
1297 if (rtx_equal_p (value, av->value)
1298 && (num_alt == 0 || av->first_insn == NULL
1299 || insn_alternatives[av->first_insn->def->insn_code]))
1300 return av;
1301
1302 av = oballoc (struct attr_value);
1303 av->value = value;
1304 av->next = attr->first_value;
1305 attr->first_value = av;
1306 av->first_insn = NULL;
1307 av->num_insns = 0;
1308 av->has_asm_insn = 0;
1309
1310 return av;
1311 }
1312
1313 /* After all DEFINE_DELAYs have been read in, create internal attributes
1314 to generate the required routines.
1315
1316 First, we compute the number of delay slots for each insn (as a COND of
1317 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1318 delay type is specified, we compute a similar function giving the
1319 DEFINE_DELAY ordinal for each insn.
1320
1321 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1322 tells whether a given insn can be in that delay slot.
1323
1324 Normal attribute filling and optimization expands these to contain the
1325 information needed to handle delay slots. */
1326
1327 static void
1328 expand_delays (void)
1329 {
1330 struct delay_desc *delay;
1331 rtx condexp;
1332 rtx newexp;
1333 int i;
1334 char *p;
1335
1336 /* First, generate data for `num_delay_slots' function. */
1337
1338 condexp = rtx_alloc (COND);
1339 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1340 XEXP (condexp, 1) = make_numeric_value (0);
1341
1342 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1343 {
1344 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1345 XVECEXP (condexp, 0, i + 1)
1346 = make_numeric_value (XVECLEN (delay->def, 1) / 3);
1347 }
1348
1349 make_internal_attr (num_delay_slots_str, condexp, ATTR_NONE);
1350
1351 /* If more than one delay type, do the same for computing the delay type. */
1352 if (num_delays > 1)
1353 {
1354 condexp = rtx_alloc (COND);
1355 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1356 XEXP (condexp, 1) = make_numeric_value (0);
1357
1358 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1359 {
1360 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1361 XVECEXP (condexp, 0, i + 1) = make_numeric_value (delay->num);
1362 }
1363
1364 make_internal_attr (delay_type_str, condexp, ATTR_SPECIAL);
1365 }
1366
1367 /* For each delay possibility and delay slot, compute an eligibility
1368 attribute for non-annulled insns and for each type of annulled (annul
1369 if true and annul if false). */
1370 for (delay = delays; delay; delay = delay->next)
1371 {
1372 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
1373 {
1374 condexp = XVECEXP (delay->def, 1, i);
1375 if (condexp == 0)
1376 condexp = false_rtx;
1377 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1378 make_numeric_value (1), make_numeric_value (0));
1379
1380 p = attr_printf (sizeof "*delay__" + MAX_DIGITS * 2,
1381 "*delay_%d_%d", delay->num, i / 3);
1382 make_internal_attr (p, newexp, ATTR_SPECIAL);
1383
1384 if (have_annul_true)
1385 {
1386 condexp = XVECEXP (delay->def, 1, i + 1);
1387 if (condexp == 0) condexp = false_rtx;
1388 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1389 make_numeric_value (1),
1390 make_numeric_value (0));
1391 p = attr_printf (sizeof "*annul_true__" + MAX_DIGITS * 2,
1392 "*annul_true_%d_%d", delay->num, i / 3);
1393 make_internal_attr (p, newexp, ATTR_SPECIAL);
1394 }
1395
1396 if (have_annul_false)
1397 {
1398 condexp = XVECEXP (delay->def, 1, i + 2);
1399 if (condexp == 0) condexp = false_rtx;
1400 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1401 make_numeric_value (1),
1402 make_numeric_value (0));
1403 p = attr_printf (sizeof "*annul_false__" + MAX_DIGITS * 2,
1404 "*annul_false_%d_%d", delay->num, i / 3);
1405 make_internal_attr (p, newexp, ATTR_SPECIAL);
1406 }
1407 }
1408 }
1409 }
1410
1411 /* Once all attributes and insns have been read and checked, we construct for
1412 each attribute value a list of all the insns that have that value for
1413 the attribute. */
1414
1415 static void
1416 fill_attr (struct attr_desc *attr)
1417 {
1418 struct attr_value *av;
1419 struct insn_ent *ie;
1420 struct insn_def *id;
1421 int i;
1422 rtx value;
1423
1424 /* Don't fill constant attributes. The value is independent of
1425 any particular insn. */
1426 if (attr->is_const)
1427 return;
1428
1429 for (id = defs; id; id = id->next)
1430 {
1431 /* If no value is specified for this insn for this attribute, use the
1432 default. */
1433 value = NULL;
1434 if (XVEC (id->def, id->vec_idx))
1435 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1436 if (! strcmp_check (XSTR (XEXP (XVECEXP (id->def, id->vec_idx, i), 0), 0),
1437 attr->name))
1438 value = XEXP (XVECEXP (id->def, id->vec_idx, i), 1);
1439
1440 if (value == NULL)
1441 av = attr->default_val;
1442 else
1443 av = get_attr_value (value, attr, id->insn_code);
1444
1445 ie = oballoc (struct insn_ent);
1446 ie->def = id;
1447 insert_insn_ent (av, ie);
1448 }
1449 }
1450
1451 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
1452 test that checks relative positions of insns (uses MATCH_DUP or PC).
1453 If so, replace it with what is obtained by passing the expression to
1454 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
1455 recursively on each value (including the default value). Otherwise,
1456 return the value returned by NO_ADDRESS_FN applied to EXP. */
1457
1458 static rtx
1459 substitute_address (rtx exp, rtx (*no_address_fn) (rtx),
1460 rtx (*address_fn) (rtx))
1461 {
1462 int i;
1463 rtx newexp;
1464
1465 if (GET_CODE (exp) == COND)
1466 {
1467 /* See if any tests use addresses. */
1468 address_used = 0;
1469 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1470 walk_attr_value (XVECEXP (exp, 0, i));
1471
1472 if (address_used)
1473 return (*address_fn) (exp);
1474
1475 /* Make a new copy of this COND, replacing each element. */
1476 newexp = rtx_alloc (COND);
1477 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
1478 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1479 {
1480 XVECEXP (newexp, 0, i) = XVECEXP (exp, 0, i);
1481 XVECEXP (newexp, 0, i + 1)
1482 = substitute_address (XVECEXP (exp, 0, i + 1),
1483 no_address_fn, address_fn);
1484 }
1485
1486 XEXP (newexp, 1) = substitute_address (XEXP (exp, 1),
1487 no_address_fn, address_fn);
1488
1489 return newexp;
1490 }
1491
1492 else if (GET_CODE (exp) == IF_THEN_ELSE)
1493 {
1494 address_used = 0;
1495 walk_attr_value (XEXP (exp, 0));
1496 if (address_used)
1497 return (*address_fn) (exp);
1498
1499 return attr_rtx (IF_THEN_ELSE,
1500 substitute_address (XEXP (exp, 0),
1501 no_address_fn, address_fn),
1502 substitute_address (XEXP (exp, 1),
1503 no_address_fn, address_fn),
1504 substitute_address (XEXP (exp, 2),
1505 no_address_fn, address_fn));
1506 }
1507
1508 return (*no_address_fn) (exp);
1509 }
1510
1511 /* Make new attributes from the `length' attribute. The following are made,
1512 each corresponding to a function called from `shorten_branches' or
1513 `get_attr_length':
1514
1515 *insn_default_length This is the length of the insn to be returned
1516 by `get_attr_length' before `shorten_branches'
1517 has been called. In each case where the length
1518 depends on relative addresses, the largest
1519 possible is used. This routine is also used
1520 to compute the initial size of the insn.
1521
1522 *insn_variable_length_p This returns 1 if the insn's length depends
1523 on relative addresses, zero otherwise.
1524
1525 *insn_current_length This is only called when it is known that the
1526 insn has a variable length and returns the
1527 current length, based on relative addresses.
1528 */
1529
1530 static void
1531 make_length_attrs (void)
1532 {
1533 static const char *new_names[] =
1534 {
1535 "*insn_default_length",
1536 "*insn_min_length",
1537 "*insn_variable_length_p",
1538 "*insn_current_length"
1539 };
1540 static rtx (*const no_address_fn[]) (rtx)
1541 = {identity_fn,identity_fn, zero_fn, zero_fn};
1542 static rtx (*const address_fn[]) (rtx)
1543 = {max_fn, min_fn, one_fn, identity_fn};
1544 size_t i;
1545 struct attr_desc *length_attr, *new_attr;
1546 struct attr_value *av, *new_av;
1547 struct insn_ent *ie, *new_ie;
1548
1549 /* See if length attribute is defined. If so, it must be numeric. Make
1550 it special so we don't output anything for it. */
1551 length_attr = find_attr (&length_str, 0);
1552 if (length_attr == 0)
1553 return;
1554
1555 if (! length_attr->is_numeric)
1556 fatal ("length attribute must be numeric");
1557
1558 length_attr->is_const = 0;
1559 length_attr->is_special = 1;
1560
1561 /* Make each new attribute, in turn. */
1562 for (i = 0; i < ARRAY_SIZE (new_names); i++)
1563 {
1564 make_internal_attr (new_names[i],
1565 substitute_address (length_attr->default_val->value,
1566 no_address_fn[i], address_fn[i]),
1567 ATTR_NONE);
1568 new_attr = find_attr (&new_names[i], 0);
1569 for (av = length_attr->first_value; av; av = av->next)
1570 for (ie = av->first_insn; ie; ie = ie->next)
1571 {
1572 new_av = get_attr_value (substitute_address (av->value,
1573 no_address_fn[i],
1574 address_fn[i]),
1575 new_attr, ie->def->insn_code);
1576 new_ie = oballoc (struct insn_ent);
1577 new_ie->def = ie->def;
1578 insert_insn_ent (new_av, new_ie);
1579 }
1580 }
1581 }
1582
1583 /* Utility functions called from above routine. */
1584
1585 static rtx
1586 identity_fn (rtx exp)
1587 {
1588 return exp;
1589 }
1590
1591 static rtx
1592 zero_fn (rtx exp ATTRIBUTE_UNUSED)
1593 {
1594 return make_numeric_value (0);
1595 }
1596
1597 static rtx
1598 one_fn (rtx exp ATTRIBUTE_UNUSED)
1599 {
1600 return make_numeric_value (1);
1601 }
1602
1603 static rtx
1604 max_fn (rtx exp)
1605 {
1606 int unknown;
1607 return make_numeric_value (max_attr_value (exp, &unknown));
1608 }
1609
1610 static rtx
1611 min_fn (rtx exp)
1612 {
1613 int unknown;
1614 return make_numeric_value (min_attr_value (exp, &unknown));
1615 }
1616
1617 static void
1618 write_length_unit_log (FILE *outf)
1619 {
1620 struct attr_desc *length_attr = find_attr (&length_str, 0);
1621 struct attr_value *av;
1622 struct insn_ent *ie;
1623 unsigned int length_unit_log, length_or;
1624 int unknown = 0;
1625
1626 if (length_attr)
1627 {
1628 length_or = or_attr_value (length_attr->default_val->value, &unknown);
1629 for (av = length_attr->first_value; av; av = av->next)
1630 for (ie = av->first_insn; ie; ie = ie->next)
1631 length_or |= or_attr_value (av->value, &unknown);
1632 }
1633
1634 if (length_attr == NULL || unknown)
1635 length_unit_log = 0;
1636 else
1637 {
1638 length_or = ~length_or;
1639 for (length_unit_log = 0; length_or & 1; length_or >>= 1)
1640 length_unit_log++;
1641 }
1642 fprintf (outf, "EXPORTED_CONST int length_unit_log = %u;\n", length_unit_log);
1643 }
1644
1645 /* Compute approximate cost of the expression. Used to decide whether
1646 expression is cheap enough for inline. */
1647 static int
1648 attr_rtx_cost (rtx x)
1649 {
1650 int cost = 1;
1651 enum rtx_code code;
1652 if (!x)
1653 return 0;
1654 code = GET_CODE (x);
1655 switch (code)
1656 {
1657 case MATCH_OPERAND:
1658 if (XSTR (x, 1)[0])
1659 return 10;
1660 else
1661 return 1;
1662
1663 case EQ_ATTR_ALT:
1664 return 1;
1665
1666 case EQ_ATTR:
1667 /* Alternatives don't result into function call. */
1668 if (!strcmp_check (XSTR (x, 0), alternative_name))
1669 return 1;
1670 else
1671 return 5;
1672 default:
1673 {
1674 int i, j;
1675 const char *fmt = GET_RTX_FORMAT (code);
1676 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1677 {
1678 switch (fmt[i])
1679 {
1680 case 'V':
1681 case 'E':
1682 for (j = 0; j < XVECLEN (x, i); j++)
1683 cost += attr_rtx_cost (XVECEXP (x, i, j));
1684 break;
1685 case 'e':
1686 cost += attr_rtx_cost (XEXP (x, i));
1687 break;
1688 }
1689 }
1690 }
1691 break;
1692 }
1693 return cost;
1694 }
1695
1696 /* Take a COND expression and see if any of the conditions in it can be
1697 simplified. If any are known true or known false for the particular insn
1698 code, the COND can be further simplified.
1699
1700 Also call ourselves on any COND operations that are values of this COND.
1701
1702 We do not modify EXP; rather, we make and return a new rtx. */
1703
1704 static rtx
1705 simplify_cond (rtx exp, int insn_code, int insn_index)
1706 {
1707 int i, j;
1708 /* We store the desired contents here,
1709 then build a new expression if they don't match EXP. */
1710 rtx defval = XEXP (exp, 1);
1711 rtx new_defval = XEXP (exp, 1);
1712 int len = XVECLEN (exp, 0);
1713 rtx *tests = XNEWVEC (rtx, len);
1714 int allsame = 1;
1715 rtx ret;
1716
1717 /* This lets us free all storage allocated below, if appropriate. */
1718 obstack_finish (rtl_obstack);
1719
1720 memcpy (tests, XVEC (exp, 0)->elem, len * sizeof (rtx));
1721
1722 /* See if default value needs simplification. */
1723 if (GET_CODE (defval) == COND)
1724 new_defval = simplify_cond (defval, insn_code, insn_index);
1725
1726 /* Simplify the subexpressions, and see what tests we can get rid of. */
1727
1728 for (i = 0; i < len; i += 2)
1729 {
1730 rtx newtest, newval;
1731
1732 /* Simplify this test. */
1733 newtest = simplify_test_exp_in_temp (tests[i], insn_code, insn_index);
1734 tests[i] = newtest;
1735
1736 newval = tests[i + 1];
1737 /* See if this value may need simplification. */
1738 if (GET_CODE (newval) == COND)
1739 newval = simplify_cond (newval, insn_code, insn_index);
1740
1741 /* Look for ways to delete or combine this test. */
1742 if (newtest == true_rtx)
1743 {
1744 /* If test is true, make this value the default
1745 and discard this + any following tests. */
1746 len = i;
1747 defval = tests[i + 1];
1748 new_defval = newval;
1749 }
1750
1751 else if (newtest == false_rtx)
1752 {
1753 /* If test is false, discard it and its value. */
1754 for (j = i; j < len - 2; j++)
1755 tests[j] = tests[j + 2];
1756 i -= 2;
1757 len -= 2;
1758 }
1759
1760 else if (i > 0 && attr_equal_p (newval, tests[i - 1]))
1761 {
1762 /* If this value and the value for the prev test are the same,
1763 merge the tests. */
1764
1765 tests[i - 2]
1766 = insert_right_side (IOR, tests[i - 2], newtest,
1767 insn_code, insn_index);
1768
1769 /* Delete this test/value. */
1770 for (j = i; j < len - 2; j++)
1771 tests[j] = tests[j + 2];
1772 len -= 2;
1773 i -= 2;
1774 }
1775
1776 else
1777 tests[i + 1] = newval;
1778 }
1779
1780 /* If the last test in a COND has the same value
1781 as the default value, that test isn't needed. */
1782
1783 while (len > 0 && attr_equal_p (tests[len - 1], new_defval))
1784 len -= 2;
1785
1786 /* See if we changed anything. */
1787 if (len != XVECLEN (exp, 0) || new_defval != XEXP (exp, 1))
1788 allsame = 0;
1789 else
1790 for (i = 0; i < len; i++)
1791 if (! attr_equal_p (tests[i], XVECEXP (exp, 0, i)))
1792 {
1793 allsame = 0;
1794 break;
1795 }
1796
1797 if (len == 0)
1798 {
1799 if (GET_CODE (defval) == COND)
1800 ret = simplify_cond (defval, insn_code, insn_index);
1801 else
1802 ret = defval;
1803 }
1804 else if (allsame)
1805 ret = exp;
1806 else
1807 {
1808 rtx newexp = rtx_alloc (COND);
1809
1810 XVEC (newexp, 0) = rtvec_alloc (len);
1811 memcpy (XVEC (newexp, 0)->elem, tests, len * sizeof (rtx));
1812 XEXP (newexp, 1) = new_defval;
1813 ret = newexp;
1814 }
1815 free (tests);
1816 return ret;
1817 }
1818
1819 /* Remove an insn entry from an attribute value. */
1820
1821 static void
1822 remove_insn_ent (struct attr_value *av, struct insn_ent *ie)
1823 {
1824 struct insn_ent *previe;
1825
1826 if (av->first_insn == ie)
1827 av->first_insn = ie->next;
1828 else
1829 {
1830 for (previe = av->first_insn; previe->next != ie; previe = previe->next)
1831 ;
1832 previe->next = ie->next;
1833 }
1834
1835 av->num_insns--;
1836 if (ie->def->insn_code == -1)
1837 av->has_asm_insn = 0;
1838
1839 num_insn_ents--;
1840 }
1841
1842 /* Insert an insn entry in an attribute value list. */
1843
1844 static void
1845 insert_insn_ent (struct attr_value *av, struct insn_ent *ie)
1846 {
1847 ie->next = av->first_insn;
1848 av->first_insn = ie;
1849 av->num_insns++;
1850 if (ie->def->insn_code == -1)
1851 av->has_asm_insn = 1;
1852
1853 num_insn_ents++;
1854 }
1855
1856 /* This is a utility routine to take an expression that is a tree of either
1857 AND or IOR expressions and insert a new term. The new term will be
1858 inserted at the right side of the first node whose code does not match
1859 the root. A new node will be created with the root's code. Its left
1860 side will be the old right side and its right side will be the new
1861 term.
1862
1863 If the `term' is itself a tree, all its leaves will be inserted. */
1864
1865 static rtx
1866 insert_right_side (enum rtx_code code, rtx exp, rtx term, int insn_code, int insn_index)
1867 {
1868 rtx newexp;
1869
1870 /* Avoid consing in some special cases. */
1871 if (code == AND && term == true_rtx)
1872 return exp;
1873 if (code == AND && term == false_rtx)
1874 return false_rtx;
1875 if (code == AND && exp == true_rtx)
1876 return term;
1877 if (code == AND && exp == false_rtx)
1878 return false_rtx;
1879 if (code == IOR && term == true_rtx)
1880 return true_rtx;
1881 if (code == IOR && term == false_rtx)
1882 return exp;
1883 if (code == IOR && exp == true_rtx)
1884 return true_rtx;
1885 if (code == IOR && exp == false_rtx)
1886 return term;
1887 if (attr_equal_p (exp, term))
1888 return exp;
1889
1890 if (GET_CODE (term) == code)
1891 {
1892 exp = insert_right_side (code, exp, XEXP (term, 0),
1893 insn_code, insn_index);
1894 exp = insert_right_side (code, exp, XEXP (term, 1),
1895 insn_code, insn_index);
1896
1897 return exp;
1898 }
1899
1900 if (GET_CODE (exp) == code)
1901 {
1902 rtx new_rtx = insert_right_side (code, XEXP (exp, 1),
1903 term, insn_code, insn_index);
1904 if (new_rtx != XEXP (exp, 1))
1905 /* Make a copy of this expression and call recursively. */
1906 newexp = attr_rtx (code, XEXP (exp, 0), new_rtx);
1907 else
1908 newexp = exp;
1909 }
1910 else
1911 {
1912 /* Insert the new term. */
1913 newexp = attr_rtx (code, exp, term);
1914 }
1915
1916 return simplify_test_exp_in_temp (newexp, insn_code, insn_index);
1917 }
1918
1919 /* If we have an expression which AND's a bunch of
1920 (not (eq_attrq "alternative" "n"))
1921 terms, we may have covered all or all but one of the possible alternatives.
1922 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
1923
1924 This routine is passed an expression and either AND or IOR. It returns a
1925 bitmask indicating which alternatives are mentioned within EXP. */
1926
1927 static uint64_t
1928 compute_alternative_mask (rtx exp, enum rtx_code code)
1929 {
1930 const char *string;
1931 if (GET_CODE (exp) == code)
1932 return compute_alternative_mask (XEXP (exp, 0), code)
1933 | compute_alternative_mask (XEXP (exp, 1), code);
1934
1935 else if (code == AND && GET_CODE (exp) == NOT
1936 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
1937 && XSTR (XEXP (exp, 0), 0) == alternative_name)
1938 string = XSTR (XEXP (exp, 0), 1);
1939
1940 else if (code == IOR && GET_CODE (exp) == EQ_ATTR
1941 && XSTR (exp, 0) == alternative_name)
1942 string = XSTR (exp, 1);
1943
1944 else if (GET_CODE (exp) == EQ_ATTR_ALT)
1945 {
1946 if (code == AND && XINT (exp, 1))
1947 return XINT (exp, 0);
1948
1949 if (code == IOR && !XINT (exp, 1))
1950 return XINT (exp, 0);
1951
1952 return 0;
1953 }
1954 else
1955 return 0;
1956
1957 if (string[1] == 0)
1958 return ((uint64_t) 1) << (string[0] - '0');
1959 return ((uint64_t) 1) << atoi (string);
1960 }
1961
1962 /* Given I, a single-bit mask, return RTX to compare the `alternative'
1963 attribute with the value represented by that bit. */
1964
1965 static rtx
1966 make_alternative_compare (uint64_t mask)
1967 {
1968 return mk_attr_alt (mask);
1969 }
1970
1971 /* If we are processing an (eq_attr "attr" "value") test, we find the value
1972 of "attr" for this insn code. From that value, we can compute a test
1973 showing when the EQ_ATTR will be true. This routine performs that
1974 computation. If a test condition involves an address, we leave the EQ_ATTR
1975 intact because addresses are only valid for the `length' attribute.
1976
1977 EXP is the EQ_ATTR expression and ATTR is the attribute to which
1978 it refers. VALUE is the value of that attribute for the insn
1979 corresponding to INSN_CODE and INSN_INDEX. */
1980
1981 static rtx
1982 evaluate_eq_attr (rtx exp, struct attr_desc *attr, rtx value,
1983 int insn_code, int insn_index)
1984 {
1985 rtx orexp, andexp;
1986 rtx right;
1987 rtx newexp;
1988 int i;
1989
1990 while (GET_CODE (value) == ATTR)
1991 {
1992 struct attr_value *av = NULL;
1993
1994 attr = find_attr (&XSTR (value, 0), 0);
1995
1996 if (insn_code_values)
1997 {
1998 struct attr_value_list *iv;
1999 for (iv = insn_code_values[insn_code]; iv; iv = iv->next)
2000 if (iv->attr == attr)
2001 {
2002 av = iv->av;
2003 break;
2004 }
2005 }
2006 else
2007 {
2008 struct insn_ent *ie;
2009 for (av = attr->first_value; av; av = av->next)
2010 for (ie = av->first_insn; ie; ie = ie->next)
2011 if (ie->def->insn_code == insn_code)
2012 goto got_av;
2013 }
2014 if (av)
2015 {
2016 got_av:
2017 value = av->value;
2018 }
2019 }
2020
2021 switch (GET_CODE (value))
2022 {
2023 case CONST_STRING:
2024 if (! strcmp_check (XSTR (value, 0), XSTR (exp, 1)))
2025 newexp = true_rtx;
2026 else
2027 newexp = false_rtx;
2028 break;
2029
2030 case SYMBOL_REF:
2031 {
2032 const char *prefix;
2033 char *string, *p;
2034
2035 gcc_assert (GET_CODE (exp) == EQ_ATTR);
2036 prefix = attr->enum_name ? attr->enum_name : attr->name;
2037 string = ACONCAT ((prefix, "_", XSTR (exp, 1), NULL));
2038 for (p = string; *p; p++)
2039 *p = TOUPPER (*p);
2040
2041 newexp = attr_rtx (EQ, value,
2042 attr_rtx (SYMBOL_REF,
2043 DEF_ATTR_STRING (string)));
2044 break;
2045 }
2046
2047 case COND:
2048 /* We construct an IOR of all the cases for which the
2049 requested attribute value is present. Since we start with
2050 FALSE, if it is not present, FALSE will be returned.
2051
2052 Each case is the AND of the NOT's of the previous conditions with the
2053 current condition; in the default case the current condition is TRUE.
2054
2055 For each possible COND value, call ourselves recursively.
2056
2057 The extra TRUE and FALSE expressions will be eliminated by another
2058 call to the simplification routine. */
2059
2060 orexp = false_rtx;
2061 andexp = true_rtx;
2062
2063 for (i = 0; i < XVECLEN (value, 0); i += 2)
2064 {
2065 rtx this_cond = simplify_test_exp_in_temp (XVECEXP (value, 0, i),
2066 insn_code, insn_index);
2067
2068 right = insert_right_side (AND, andexp, this_cond,
2069 insn_code, insn_index);
2070 right = insert_right_side (AND, right,
2071 evaluate_eq_attr (exp, attr,
2072 XVECEXP (value, 0,
2073 i + 1),
2074 insn_code, insn_index),
2075 insn_code, insn_index);
2076 orexp = insert_right_side (IOR, orexp, right,
2077 insn_code, insn_index);
2078
2079 /* Add this condition into the AND expression. */
2080 newexp = attr_rtx (NOT, this_cond);
2081 andexp = insert_right_side (AND, andexp, newexp,
2082 insn_code, insn_index);
2083 }
2084
2085 /* Handle the default case. */
2086 right = insert_right_side (AND, andexp,
2087 evaluate_eq_attr (exp, attr, XEXP (value, 1),
2088 insn_code, insn_index),
2089 insn_code, insn_index);
2090 newexp = insert_right_side (IOR, orexp, right, insn_code, insn_index);
2091 break;
2092
2093 default:
2094 gcc_unreachable ();
2095 }
2096
2097 /* If uses an address, must return original expression. But set the
2098 ATTR_IND_SIMPLIFIED_P bit so we don't try to simplify it again. */
2099
2100 address_used = 0;
2101 walk_attr_value (newexp);
2102
2103 if (address_used)
2104 {
2105 if (! ATTR_IND_SIMPLIFIED_P (exp))
2106 return copy_rtx_unchanging (exp);
2107 return exp;
2108 }
2109 else
2110 return newexp;
2111 }
2112
2113 /* This routine is called when an AND of a term with a tree of AND's is
2114 encountered. If the term or its complement is present in the tree, it
2115 can be replaced with TRUE or FALSE, respectively.
2116
2117 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2118 be true and hence are complementary.
2119
2120 There is one special case: If we see
2121 (and (not (eq_attr "att" "v1"))
2122 (eq_attr "att" "v2"))
2123 this can be replaced by (eq_attr "att" "v2"). To do this we need to
2124 replace the term, not anything in the AND tree. So we pass a pointer to
2125 the term. */
2126
2127 static rtx
2128 simplify_and_tree (rtx exp, rtx *pterm, int insn_code, int insn_index)
2129 {
2130 rtx left, right;
2131 rtx newexp;
2132 rtx temp;
2133 int left_eliminates_term, right_eliminates_term;
2134
2135 if (GET_CODE (exp) == AND)
2136 {
2137 left = simplify_and_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
2138 right = simplify_and_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2139 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2140 {
2141 newexp = attr_rtx (AND, left, right);
2142
2143 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2144 }
2145 }
2146
2147 else if (GET_CODE (exp) == IOR)
2148 {
2149 /* For the IOR case, we do the same as above, except that we can
2150 only eliminate `term' if both sides of the IOR would do so. */
2151 temp = *pterm;
2152 left = simplify_and_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
2153 left_eliminates_term = (temp == true_rtx);
2154
2155 temp = *pterm;
2156 right = simplify_and_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2157 right_eliminates_term = (temp == true_rtx);
2158
2159 if (left_eliminates_term && right_eliminates_term)
2160 *pterm = true_rtx;
2161
2162 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2163 {
2164 newexp = attr_rtx (IOR, left, right);
2165
2166 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2167 }
2168 }
2169
2170 /* Check for simplifications. Do some extra checking here since this
2171 routine is called so many times. */
2172
2173 if (exp == *pterm)
2174 return true_rtx;
2175
2176 else if (GET_CODE (exp) == NOT && XEXP (exp, 0) == *pterm)
2177 return false_rtx;
2178
2179 else if (GET_CODE (*pterm) == NOT && exp == XEXP (*pterm, 0))
2180 return false_rtx;
2181
2182 else if (GET_CODE (exp) == EQ_ATTR_ALT && GET_CODE (*pterm) == EQ_ATTR_ALT)
2183 {
2184 if (attr_alt_subset_p (*pterm, exp))
2185 return true_rtx;
2186
2187 if (attr_alt_subset_of_compl_p (*pterm, exp))
2188 return false_rtx;
2189
2190 if (attr_alt_subset_p (exp, *pterm))
2191 *pterm = true_rtx;
2192
2193 return exp;
2194 }
2195
2196 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == EQ_ATTR)
2197 {
2198 if (XSTR (exp, 0) != XSTR (*pterm, 0))
2199 return exp;
2200
2201 if (! strcmp_check (XSTR (exp, 1), XSTR (*pterm, 1)))
2202 return true_rtx;
2203 else
2204 return false_rtx;
2205 }
2206
2207 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
2208 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
2209 {
2210 if (XSTR (*pterm, 0) != XSTR (XEXP (exp, 0), 0))
2211 return exp;
2212
2213 if (! strcmp_check (XSTR (*pterm, 1), XSTR (XEXP (exp, 0), 1)))
2214 return false_rtx;
2215 else
2216 return true_rtx;
2217 }
2218
2219 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
2220 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR)
2221 {
2222 if (XSTR (exp, 0) != XSTR (XEXP (*pterm, 0), 0))
2223 return exp;
2224
2225 if (! strcmp_check (XSTR (exp, 1), XSTR (XEXP (*pterm, 0), 1)))
2226 return false_rtx;
2227 else
2228 *pterm = true_rtx;
2229 }
2230
2231 else if (GET_CODE (exp) == NOT && GET_CODE (*pterm) == NOT)
2232 {
2233 if (attr_equal_p (XEXP (exp, 0), XEXP (*pterm, 0)))
2234 return true_rtx;
2235 }
2236
2237 else if (GET_CODE (exp) == NOT)
2238 {
2239 if (attr_equal_p (XEXP (exp, 0), *pterm))
2240 return false_rtx;
2241 }
2242
2243 else if (GET_CODE (*pterm) == NOT)
2244 {
2245 if (attr_equal_p (XEXP (*pterm, 0), exp))
2246 return false_rtx;
2247 }
2248
2249 else if (attr_equal_p (exp, *pterm))
2250 return true_rtx;
2251
2252 return exp;
2253 }
2254
2255 /* Similar to `simplify_and_tree', but for IOR trees. */
2256
2257 static rtx
2258 simplify_or_tree (rtx exp, rtx *pterm, int insn_code, int insn_index)
2259 {
2260 rtx left, right;
2261 rtx newexp;
2262 rtx temp;
2263 int left_eliminates_term, right_eliminates_term;
2264
2265 if (GET_CODE (exp) == IOR)
2266 {
2267 left = simplify_or_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
2268 right = simplify_or_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2269 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2270 {
2271 newexp = attr_rtx (GET_CODE (exp), left, right);
2272
2273 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2274 }
2275 }
2276
2277 else if (GET_CODE (exp) == AND)
2278 {
2279 /* For the AND case, we do the same as above, except that we can
2280 only eliminate `term' if both sides of the AND would do so. */
2281 temp = *pterm;
2282 left = simplify_or_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
2283 left_eliminates_term = (temp == false_rtx);
2284
2285 temp = *pterm;
2286 right = simplify_or_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2287 right_eliminates_term = (temp == false_rtx);
2288
2289 if (left_eliminates_term && right_eliminates_term)
2290 *pterm = false_rtx;
2291
2292 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2293 {
2294 newexp = attr_rtx (GET_CODE (exp), left, right);
2295
2296 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2297 }
2298 }
2299
2300 if (attr_equal_p (exp, *pterm))
2301 return false_rtx;
2302
2303 else if (GET_CODE (exp) == NOT && attr_equal_p (XEXP (exp, 0), *pterm))
2304 return true_rtx;
2305
2306 else if (GET_CODE (*pterm) == NOT && attr_equal_p (XEXP (*pterm, 0), exp))
2307 return true_rtx;
2308
2309 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
2310 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
2311 && XSTR (*pterm, 0) == XSTR (XEXP (exp, 0), 0))
2312 *pterm = false_rtx;
2313
2314 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
2315 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR
2316 && XSTR (exp, 0) == XSTR (XEXP (*pterm, 0), 0))
2317 return false_rtx;
2318
2319 return exp;
2320 }
2321
2322 /* Simplify test expression and use temporary obstack in order to avoid
2323 memory bloat. Use ATTR_IND_SIMPLIFIED to avoid unnecessary simplifications
2324 and avoid unnecessary copying if possible. */
2325
2326 static rtx
2327 simplify_test_exp_in_temp (rtx exp, int insn_code, int insn_index)
2328 {
2329 rtx x;
2330 struct obstack *old;
2331 if (ATTR_IND_SIMPLIFIED_P (exp))
2332 return exp;
2333 old = rtl_obstack;
2334 rtl_obstack = temp_obstack;
2335 x = simplify_test_exp (exp, insn_code, insn_index);
2336 rtl_obstack = old;
2337 if (x == exp || rtl_obstack == temp_obstack)
2338 return x;
2339 return attr_copy_rtx (x);
2340 }
2341
2342 /* Returns true if S1 is a subset of S2. */
2343
2344 static bool
2345 attr_alt_subset_p (rtx s1, rtx s2)
2346 {
2347 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2348 {
2349 case (0 << 1) | 0:
2350 return !(XINT (s1, 0) &~ XINT (s2, 0));
2351
2352 case (0 << 1) | 1:
2353 return !(XINT (s1, 0) & XINT (s2, 0));
2354
2355 case (1 << 1) | 0:
2356 return false;
2357
2358 case (1 << 1) | 1:
2359 return !(XINT (s2, 0) &~ XINT (s1, 0));
2360
2361 default:
2362 gcc_unreachable ();
2363 }
2364 }
2365
2366 /* Returns true if S1 is a subset of complement of S2. */
2367
2368 static bool
2369 attr_alt_subset_of_compl_p (rtx s1, rtx s2)
2370 {
2371 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2372 {
2373 case (0 << 1) | 0:
2374 return !(XINT (s1, 0) & XINT (s2, 0));
2375
2376 case (0 << 1) | 1:
2377 return !(XINT (s1, 0) & ~XINT (s2, 0));
2378
2379 case (1 << 1) | 0:
2380 return !(XINT (s2, 0) &~ XINT (s1, 0));
2381
2382 case (1 << 1) | 1:
2383 return false;
2384
2385 default:
2386 gcc_unreachable ();
2387 }
2388 }
2389
2390 /* Return EQ_ATTR_ALT expression representing intersection of S1 and S2. */
2391
2392 static rtx
2393 attr_alt_intersection (rtx s1, rtx s2)
2394 {
2395 rtx result = rtx_alloc (EQ_ATTR_ALT);
2396
2397 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2398 {
2399 case (0 << 1) | 0:
2400 XINT (result, 0) = XINT (s1, 0) & XINT (s2, 0);
2401 break;
2402 case (0 << 1) | 1:
2403 XINT (result, 0) = XINT (s1, 0) & ~XINT (s2, 0);
2404 break;
2405 case (1 << 1) | 0:
2406 XINT (result, 0) = XINT (s2, 0) & ~XINT (s1, 0);
2407 break;
2408 case (1 << 1) | 1:
2409 XINT (result, 0) = XINT (s1, 0) | XINT (s2, 0);
2410 break;
2411 default:
2412 gcc_unreachable ();
2413 }
2414 XINT (result, 1) = XINT (s1, 1) & XINT (s2, 1);
2415
2416 return result;
2417 }
2418
2419 /* Return EQ_ATTR_ALT expression representing union of S1 and S2. */
2420
2421 static rtx
2422 attr_alt_union (rtx s1, rtx s2)
2423 {
2424 rtx result = rtx_alloc (EQ_ATTR_ALT);
2425
2426 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2427 {
2428 case (0 << 1) | 0:
2429 XINT (result, 0) = XINT (s1, 0) | XINT (s2, 0);
2430 break;
2431 case (0 << 1) | 1:
2432 XINT (result, 0) = XINT (s2, 0) & ~XINT (s1, 0);
2433 break;
2434 case (1 << 1) | 0:
2435 XINT (result, 0) = XINT (s1, 0) & ~XINT (s2, 0);
2436 break;
2437 case (1 << 1) | 1:
2438 XINT (result, 0) = XINT (s1, 0) & XINT (s2, 0);
2439 break;
2440 default:
2441 gcc_unreachable ();
2442 }
2443
2444 XINT (result, 1) = XINT (s1, 1) | XINT (s2, 1);
2445 return result;
2446 }
2447
2448 /* Return EQ_ATTR_ALT expression representing complement of S. */
2449
2450 static rtx
2451 attr_alt_complement (rtx s)
2452 {
2453 rtx result = rtx_alloc (EQ_ATTR_ALT);
2454
2455 XINT (result, 0) = XINT (s, 0);
2456 XINT (result, 1) = 1 - XINT (s, 1);
2457
2458 return result;
2459 }
2460
2461 /* Return EQ_ATTR_ALT expression representing set containing elements set
2462 in E. */
2463
2464 static rtx
2465 mk_attr_alt (uint64_t e)
2466 {
2467 rtx result = rtx_alloc (EQ_ATTR_ALT);
2468
2469 XINT (result, 0) = e;
2470 XINT (result, 1) = 0;
2471
2472 return result;
2473 }
2474
2475 /* Given an expression, see if it can be simplified for a particular insn
2476 code based on the values of other attributes being tested. This can
2477 eliminate nested get_attr_... calls.
2478
2479 Note that if an endless recursion is specified in the patterns, the
2480 optimization will loop. However, it will do so in precisely the cases where
2481 an infinite recursion loop could occur during compilation. It's better that
2482 it occurs here! */
2483
2484 static rtx
2485 simplify_test_exp (rtx exp, int insn_code, int insn_index)
2486 {
2487 rtx left, right;
2488 struct attr_desc *attr;
2489 struct attr_value *av;
2490 struct insn_ent *ie;
2491 struct attr_value_list *iv;
2492 uint64_t i;
2493 rtx newexp = exp;
2494 bool left_alt, right_alt;
2495
2496 /* Don't re-simplify something we already simplified. */
2497 if (ATTR_IND_SIMPLIFIED_P (exp) || ATTR_CURR_SIMPLIFIED_P (exp))
2498 return exp;
2499
2500 switch (GET_CODE (exp))
2501 {
2502 case AND:
2503 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2504 if (left == false_rtx)
2505 return false_rtx;
2506 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
2507 if (right == false_rtx)
2508 return false_rtx;
2509
2510 if (GET_CODE (left) == EQ_ATTR_ALT
2511 && GET_CODE (right) == EQ_ATTR_ALT)
2512 {
2513 exp = attr_alt_intersection (left, right);
2514 return simplify_test_exp (exp, insn_code, insn_index);
2515 }
2516
2517 /* If either side is an IOR and we have (eq_attr "alternative" ..")
2518 present on both sides, apply the distributive law since this will
2519 yield simplifications. */
2520 if ((GET_CODE (left) == IOR || GET_CODE (right) == IOR)
2521 && compute_alternative_mask (left, IOR)
2522 && compute_alternative_mask (right, IOR))
2523 {
2524 if (GET_CODE (left) == IOR)
2525 std::swap (left, right);
2526
2527 newexp = attr_rtx (IOR,
2528 attr_rtx (AND, left, XEXP (right, 0)),
2529 attr_rtx (AND, left, XEXP (right, 1)));
2530
2531 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2532 }
2533
2534 /* Try with the term on both sides. */
2535 right = simplify_and_tree (right, &left, insn_code, insn_index);
2536 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
2537 left = simplify_and_tree (left, &right, insn_code, insn_index);
2538
2539 if (left == false_rtx || right == false_rtx)
2540 return false_rtx;
2541 else if (left == true_rtx)
2542 {
2543 return right;
2544 }
2545 else if (right == true_rtx)
2546 {
2547 return left;
2548 }
2549 /* See if all or all but one of the insn's alternatives are specified
2550 in this tree. Optimize if so. */
2551
2552 if (GET_CODE (left) == NOT)
2553 left_alt = (GET_CODE (XEXP (left, 0)) == EQ_ATTR
2554 && XSTR (XEXP (left, 0), 0) == alternative_name);
2555 else
2556 left_alt = (GET_CODE (left) == EQ_ATTR_ALT
2557 && XINT (left, 1));
2558
2559 if (GET_CODE (right) == NOT)
2560 right_alt = (GET_CODE (XEXP (right, 0)) == EQ_ATTR
2561 && XSTR (XEXP (right, 0), 0) == alternative_name);
2562 else
2563 right_alt = (GET_CODE (right) == EQ_ATTR_ALT
2564 && XINT (right, 1));
2565
2566 if (insn_code >= 0
2567 && (GET_CODE (left) == AND
2568 || left_alt
2569 || GET_CODE (right) == AND
2570 || right_alt))
2571 {
2572 i = compute_alternative_mask (exp, AND);
2573 if (i & ~insn_alternatives[insn_code])
2574 fatal ("invalid alternative specified for pattern number %d",
2575 insn_index);
2576
2577 /* If all alternatives are excluded, this is false. */
2578 i ^= insn_alternatives[insn_code];
2579 if (i == 0)
2580 return false_rtx;
2581 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
2582 {
2583 /* If just one excluded, AND a comparison with that one to the
2584 front of the tree. The others will be eliminated by
2585 optimization. We do not want to do this if the insn has one
2586 alternative and we have tested none of them! */
2587 left = make_alternative_compare (i);
2588 right = simplify_and_tree (exp, &left, insn_code, insn_index);
2589 newexp = attr_rtx (AND, left, right);
2590
2591 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2592 }
2593 }
2594
2595 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2596 {
2597 newexp = attr_rtx (AND, left, right);
2598 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2599 }
2600 break;
2601
2602 case IOR:
2603 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2604 if (left == true_rtx)
2605 return true_rtx;
2606 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
2607 if (right == true_rtx)
2608 return true_rtx;
2609
2610 if (GET_CODE (left) == EQ_ATTR_ALT
2611 && GET_CODE (right) == EQ_ATTR_ALT)
2612 {
2613 exp = attr_alt_union (left, right);
2614 return simplify_test_exp (exp, insn_code, insn_index);
2615 }
2616
2617 right = simplify_or_tree (right, &left, insn_code, insn_index);
2618 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
2619 left = simplify_or_tree (left, &right, insn_code, insn_index);
2620
2621 if (right == true_rtx || left == true_rtx)
2622 return true_rtx;
2623 else if (left == false_rtx)
2624 {
2625 return right;
2626 }
2627 else if (right == false_rtx)
2628 {
2629 return left;
2630 }
2631
2632 /* Test for simple cases where the distributive law is useful. I.e.,
2633 convert (ior (and (x) (y))
2634 (and (x) (z)))
2635 to (and (x)
2636 (ior (y) (z)))
2637 */
2638
2639 else if (GET_CODE (left) == AND && GET_CODE (right) == AND
2640 && attr_equal_p (XEXP (left, 0), XEXP (right, 0)))
2641 {
2642 newexp = attr_rtx (IOR, XEXP (left, 1), XEXP (right, 1));
2643
2644 left = XEXP (left, 0);
2645 right = newexp;
2646 newexp = attr_rtx (AND, left, right);
2647 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2648 }
2649
2650 /* Similarly,
2651 convert (ior (and (y) (x))
2652 (and (z) (x)))
2653 to (and (ior (y) (z))
2654 (x))
2655 Note that we want the common term to stay at the end.
2656 */
2657
2658 else if (GET_CODE (left) == AND && GET_CODE (right) == AND
2659 && attr_equal_p (XEXP (left, 1), XEXP (right, 1)))
2660 {
2661 newexp = attr_rtx (IOR, XEXP (left, 0), XEXP (right, 0));
2662
2663 left = newexp;
2664 right = XEXP (right, 1);
2665 newexp = attr_rtx (AND, left, right);
2666 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2667 }
2668
2669 /* See if all or all but one of the insn's alternatives are specified
2670 in this tree. Optimize if so. */
2671
2672 else if (insn_code >= 0
2673 && (GET_CODE (left) == IOR
2674 || (GET_CODE (left) == EQ_ATTR_ALT
2675 && !XINT (left, 1))
2676 || (GET_CODE (left) == EQ_ATTR
2677 && XSTR (left, 0) == alternative_name)
2678 || GET_CODE (right) == IOR
2679 || (GET_CODE (right) == EQ_ATTR_ALT
2680 && !XINT (right, 1))
2681 || (GET_CODE (right) == EQ_ATTR
2682 && XSTR (right, 0) == alternative_name)))
2683 {
2684 i = compute_alternative_mask (exp, IOR);
2685 if (i & ~insn_alternatives[insn_code])
2686 fatal ("invalid alternative specified for pattern number %d",
2687 insn_index);
2688
2689 /* If all alternatives are included, this is true. */
2690 i ^= insn_alternatives[insn_code];
2691 if (i == 0)
2692 return true_rtx;
2693 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
2694 {
2695 /* If just one excluded, IOR a comparison with that one to the
2696 front of the tree. The others will be eliminated by
2697 optimization. We do not want to do this if the insn has one
2698 alternative and we have tested none of them! */
2699 left = make_alternative_compare (i);
2700 right = simplify_and_tree (exp, &left, insn_code, insn_index);
2701 newexp = attr_rtx (IOR, attr_rtx (NOT, left), right);
2702
2703 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2704 }
2705 }
2706
2707 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2708 {
2709 newexp = attr_rtx (IOR, left, right);
2710 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2711 }
2712 break;
2713
2714 case NOT:
2715 if (GET_CODE (XEXP (exp, 0)) == NOT)
2716 {
2717 left = SIMPLIFY_TEST_EXP (XEXP (XEXP (exp, 0), 0),
2718 insn_code, insn_index);
2719 return left;
2720 }
2721
2722 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2723 if (GET_CODE (left) == NOT)
2724 return XEXP (left, 0);
2725
2726 if (left == false_rtx)
2727 return true_rtx;
2728 if (left == true_rtx)
2729 return false_rtx;
2730
2731 if (GET_CODE (left) == EQ_ATTR_ALT)
2732 {
2733 exp = attr_alt_complement (left);
2734 return simplify_test_exp (exp, insn_code, insn_index);
2735 }
2736
2737 /* Try to apply De`Morgan's laws. */
2738 if (GET_CODE (left) == IOR)
2739 {
2740 newexp = attr_rtx (AND,
2741 attr_rtx (NOT, XEXP (left, 0)),
2742 attr_rtx (NOT, XEXP (left, 1)));
2743
2744 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2745 }
2746 else if (GET_CODE (left) == AND)
2747 {
2748 newexp = attr_rtx (IOR,
2749 attr_rtx (NOT, XEXP (left, 0)),
2750 attr_rtx (NOT, XEXP (left, 1)));
2751
2752 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2753 }
2754 else if (left != XEXP (exp, 0))
2755 {
2756 newexp = attr_rtx (NOT, left);
2757 }
2758 break;
2759
2760 case EQ_ATTR_ALT:
2761 if (!XINT (exp, 0))
2762 return XINT (exp, 1) ? true_rtx : false_rtx;
2763 break;
2764
2765 case EQ_ATTR:
2766 if (XSTR (exp, 0) == alternative_name)
2767 {
2768 newexp = mk_attr_alt (((uint64_t) 1) << atoi (XSTR (exp, 1)));
2769 break;
2770 }
2771
2772 /* Look at the value for this insn code in the specified attribute.
2773 We normally can replace this comparison with the condition that
2774 would give this insn the values being tested for. */
2775 if (insn_code >= 0
2776 && (attr = find_attr (&XSTR (exp, 0), 0)) != NULL)
2777 {
2778 rtx x;
2779
2780 av = NULL;
2781 if (insn_code_values)
2782 {
2783 for (iv = insn_code_values[insn_code]; iv; iv = iv->next)
2784 if (iv->attr == attr)
2785 {
2786 av = iv->av;
2787 break;
2788 }
2789 }
2790 else
2791 {
2792 for (av = attr->first_value; av; av = av->next)
2793 for (ie = av->first_insn; ie; ie = ie->next)
2794 if (ie->def->insn_code == insn_code)
2795 goto got_av;
2796 }
2797
2798 if (av)
2799 {
2800 got_av:
2801 x = evaluate_eq_attr (exp, attr, av->value,
2802 insn_code, insn_index);
2803 x = SIMPLIFY_TEST_EXP (x, insn_code, insn_index);
2804 if (attr_rtx_cost (x) < 7)
2805 return x;
2806 }
2807 }
2808 break;
2809
2810 default:
2811 break;
2812 }
2813
2814 /* We have already simplified this expression. Simplifying it again
2815 won't buy anything unless we weren't given a valid insn code
2816 to process (i.e., we are canonicalizing something.). */
2817 if (insn_code != -2
2818 && ! ATTR_IND_SIMPLIFIED_P (newexp))
2819 return copy_rtx_unchanging (newexp);
2820
2821 return newexp;
2822 }
2823
2824 /* Return 1 if any EQ_ATTR subexpression of P refers to ATTR,
2825 otherwise return 0. */
2826
2827 static int
2828 tests_attr_p (rtx p, struct attr_desc *attr)
2829 {
2830 const char *fmt;
2831 int i, ie, j, je;
2832
2833 if (GET_CODE (p) == EQ_ATTR)
2834 {
2835 if (XSTR (p, 0) != attr->name)
2836 return 0;
2837 return 1;
2838 }
2839
2840 fmt = GET_RTX_FORMAT (GET_CODE (p));
2841 ie = GET_RTX_LENGTH (GET_CODE (p));
2842 for (i = 0; i < ie; i++)
2843 {
2844 switch (*fmt++)
2845 {
2846 case 'e':
2847 if (tests_attr_p (XEXP (p, i), attr))
2848 return 1;
2849 break;
2850
2851 case 'E':
2852 je = XVECLEN (p, i);
2853 for (j = 0; j < je; ++j)
2854 if (tests_attr_p (XVECEXP (p, i, j), attr))
2855 return 1;
2856 break;
2857 }
2858 }
2859
2860 return 0;
2861 }
2862
2863 /* Calculate a topological sorting of all attributes so that
2864 all attributes only depend on attributes in front of it.
2865 Place the result in *RET (which is a pointer to an array of
2866 attr_desc pointers), and return the size of that array. */
2867
2868 static int
2869 get_attr_order (struct attr_desc ***ret)
2870 {
2871 int i, j;
2872 int num = 0;
2873 struct attr_desc *attr;
2874 struct attr_desc **all, **sorted;
2875 char *handled;
2876 for (i = 0; i < MAX_ATTRS_INDEX; i++)
2877 for (attr = attrs[i]; attr; attr = attr->next)
2878 num++;
2879 all = XNEWVEC (struct attr_desc *, num);
2880 sorted = XNEWVEC (struct attr_desc *, num);
2881 handled = XCNEWVEC (char, num);
2882 num = 0;
2883 for (i = 0; i < MAX_ATTRS_INDEX; i++)
2884 for (attr = attrs[i]; attr; attr = attr->next)
2885 all[num++] = attr;
2886
2887 j = 0;
2888 for (i = 0; i < num; i++)
2889 if (all[i]->is_const)
2890 handled[i] = 1, sorted[j++] = all[i];
2891
2892 /* We have only few attributes hence we can live with the inner
2893 loop being O(n^2), unlike the normal fast variants of topological
2894 sorting. */
2895 while (j < num)
2896 {
2897 for (i = 0; i < num; i++)
2898 if (!handled[i])
2899 {
2900 /* Let's see if I depends on anything interesting. */
2901 int k;
2902 for (k = 0; k < num; k++)
2903 if (!handled[k])
2904 {
2905 struct attr_value *av;
2906 for (av = all[i]->first_value; av; av = av->next)
2907 if (av->num_insns != 0)
2908 if (tests_attr_p (av->value, all[k]))
2909 break;
2910
2911 if (av)
2912 /* Something in I depends on K. */
2913 break;
2914 }
2915 if (k == num)
2916 {
2917 /* Nothing in I depended on anything intersting, so
2918 it's done. */
2919 handled[i] = 1;
2920 sorted[j++] = all[i];
2921 }
2922 }
2923 }
2924
2925 if (DEBUG)
2926 for (j = 0; j < num; j++)
2927 {
2928 struct attr_desc *attr2;
2929 struct attr_value *av;
2930
2931 attr = sorted[j];
2932 fprintf (stderr, "%s depends on: ", attr->name);
2933 for (i = 0; i < MAX_ATTRS_INDEX; ++i)
2934 for (attr2 = attrs[i]; attr2; attr2 = attr2->next)
2935 if (!attr2->is_const)
2936 for (av = attr->first_value; av; av = av->next)
2937 if (av->num_insns != 0)
2938 if (tests_attr_p (av->value, attr2))
2939 {
2940 fprintf (stderr, "%s, ", attr2->name);
2941 break;
2942 }
2943 fprintf (stderr, "\n");
2944 }
2945
2946 free (all);
2947 *ret = sorted;
2948 return num;
2949 }
2950
2951 /* Optimize the attribute lists by seeing if we can determine conditional
2952 values from the known values of other attributes. This will save subroutine
2953 calls during the compilation. */
2954
2955 static void
2956 optimize_attrs (void)
2957 {
2958 struct attr_desc *attr;
2959 struct attr_value *av;
2960 struct insn_ent *ie;
2961 rtx newexp;
2962 int i;
2963 struct attr_value_list *ivbuf;
2964 struct attr_value_list *iv;
2965 struct attr_desc **topsort;
2966 int topnum;
2967
2968 /* For each insn code, make a list of all the insn_ent's for it,
2969 for all values for all attributes. */
2970
2971 if (num_insn_ents == 0)
2972 return;
2973
2974 /* Make 2 extra elements, for "code" values -2 and -1. */
2975 insn_code_values = XCNEWVEC (struct attr_value_list *, insn_code_number + 2);
2976
2977 /* Offset the table address so we can index by -2 or -1. */
2978 insn_code_values += 2;
2979
2980 iv = ivbuf = XNEWVEC (struct attr_value_list, num_insn_ents);
2981
2982 /* Create the chain of insn*attr values such that we see dependend
2983 attributes after their dependencies. As we use a stack via the
2984 next pointers start from the end of the topological order. */
2985 topnum = get_attr_order (&topsort);
2986 for (i = topnum - 1; i >= 0; i--)
2987 for (av = topsort[i]->first_value; av; av = av->next)
2988 for (ie = av->first_insn; ie; ie = ie->next)
2989 {
2990 iv->attr = topsort[i];
2991 iv->av = av;
2992 iv->ie = ie;
2993 iv->next = insn_code_values[ie->def->insn_code];
2994 insn_code_values[ie->def->insn_code] = iv;
2995 iv++;
2996 }
2997 free (topsort);
2998
2999 /* Sanity check on num_insn_ents. */
3000 gcc_assert (iv == ivbuf + num_insn_ents);
3001
3002 /* Process one insn code at a time. */
3003 for (i = -2; i < insn_code_number; i++)
3004 {
3005 /* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere relevant.
3006 We use it to mean "already simplified for this insn". */
3007 for (iv = insn_code_values[i]; iv; iv = iv->next)
3008 clear_struct_flag (iv->av->value);
3009
3010 for (iv = insn_code_values[i]; iv; iv = iv->next)
3011 {
3012 struct obstack *old = rtl_obstack;
3013
3014 attr = iv->attr;
3015 av = iv->av;
3016 ie = iv->ie;
3017 if (GET_CODE (av->value) != COND)
3018 continue;
3019
3020 rtl_obstack = temp_obstack;
3021 newexp = av->value;
3022 while (GET_CODE (newexp) == COND)
3023 {
3024 rtx newexp2 = simplify_cond (newexp, ie->def->insn_code,
3025 ie->def->insn_index);
3026 if (newexp2 == newexp)
3027 break;
3028 newexp = newexp2;
3029 }
3030
3031 rtl_obstack = old;
3032 /* If we created a new value for this instruction, and it's
3033 cheaper than the old value, and overall cheap, use that
3034 one as specific value for the current instruction.
3035 The last test is to avoid exploding the get_attr_ function
3036 sizes for no much gain. */
3037 if (newexp != av->value
3038 && attr_rtx_cost (newexp) < attr_rtx_cost (av->value)
3039 && attr_rtx_cost (newexp) < 26
3040 )
3041 {
3042 newexp = attr_copy_rtx (newexp);
3043 remove_insn_ent (av, ie);
3044 av = get_attr_value (newexp, attr, ie->def->insn_code);
3045 iv->av = av;
3046 insert_insn_ent (av, ie);
3047 }
3048 }
3049 }
3050
3051 free (ivbuf);
3052 free (insn_code_values - 2);
3053 insn_code_values = NULL;
3054 }
3055
3056 /* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions. */
3057
3058 static void
3059 clear_struct_flag (rtx x)
3060 {
3061 int i;
3062 int j;
3063 enum rtx_code code;
3064 const char *fmt;
3065
3066 ATTR_CURR_SIMPLIFIED_P (x) = 0;
3067 if (ATTR_IND_SIMPLIFIED_P (x))
3068 return;
3069
3070 code = GET_CODE (x);
3071
3072 switch (code)
3073 {
3074 case REG:
3075 CASE_CONST_ANY:
3076 case MATCH_TEST:
3077 case SYMBOL_REF:
3078 case CODE_LABEL:
3079 case PC:
3080 case CC0:
3081 case EQ_ATTR:
3082 case ATTR_FLAG:
3083 return;
3084
3085 default:
3086 break;
3087 }
3088
3089 /* Compare the elements. If any pair of corresponding elements
3090 fail to match, return 0 for the whole things. */
3091
3092 fmt = GET_RTX_FORMAT (code);
3093 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
3094 {
3095 switch (fmt[i])
3096 {
3097 case 'V':
3098 case 'E':
3099 for (j = 0; j < XVECLEN (x, i); j++)
3100 clear_struct_flag (XVECEXP (x, i, j));
3101 break;
3102
3103 case 'e':
3104 clear_struct_flag (XEXP (x, i));
3105 break;
3106 }
3107 }
3108 }
3109
3110 /* Add attribute value NAME to the beginning of ATTR's list. */
3111
3112 static void
3113 add_attr_value (struct attr_desc *attr, const char *name)
3114 {
3115 struct attr_value *av;
3116
3117 av = oballoc (struct attr_value);
3118 av->value = attr_rtx (CONST_STRING, name);
3119 av->next = attr->first_value;
3120 attr->first_value = av;
3121 av->first_insn = NULL;
3122 av->num_insns = 0;
3123 av->has_asm_insn = 0;
3124 }
3125
3126 /* Create table entries for DEFINE_ATTR or DEFINE_ENUM_ATTR. */
3127
3128 static void
3129 gen_attr (rtx exp, int lineno)
3130 {
3131 struct enum_type *et;
3132 struct enum_value *ev;
3133 struct attr_desc *attr;
3134 const char *name_ptr;
3135 char *p;
3136
3137 /* Make a new attribute structure. Check for duplicate by looking at
3138 attr->default_val, since it is initialized by this routine. */
3139 attr = find_attr (&XSTR (exp, 0), 1);
3140 if (attr->default_val)
3141 {
3142 error_with_line (lineno, "duplicate definition for attribute %s",
3143 attr->name);
3144 message_at (attr->loc, "previous definition");
3145 return;
3146 }
3147 attr->loc = file_location (read_md_filename, lineno);
3148
3149 if (GET_CODE (exp) == DEFINE_ENUM_ATTR)
3150 {
3151 attr->enum_name = XSTR (exp, 1);
3152 et = lookup_enum_type (XSTR (exp, 1));
3153 if (!et || !et->md_p)
3154 error_with_line (lineno, "No define_enum called `%s' defined",
3155 attr->name);
3156 if (et)
3157 for (ev = et->values; ev; ev = ev->next)
3158 add_attr_value (attr, ev->name);
3159 }
3160 else if (*XSTR (exp, 1) == '\0')
3161 attr->is_numeric = 1;
3162 else
3163 {
3164 name_ptr = XSTR (exp, 1);
3165 while ((p = next_comma_elt (&name_ptr)) != NULL)
3166 add_attr_value (attr, p);
3167 }
3168
3169 if (GET_CODE (XEXP (exp, 2)) == CONST)
3170 {
3171 attr->is_const = 1;
3172 if (attr->is_numeric)
3173 error_with_line (lineno,
3174 "constant attributes may not take numeric values");
3175
3176 /* Get rid of the CONST node. It is allowed only at top-level. */
3177 XEXP (exp, 2) = XEXP (XEXP (exp, 2), 0);
3178 }
3179
3180 if (! strcmp_check (attr->name, length_str) && ! attr->is_numeric)
3181 error_with_line (lineno, "`length' attribute must take numeric values");
3182
3183 /* Set up the default value. */
3184 XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
3185 attr->default_val = get_attr_value (XEXP (exp, 2), attr, -2);
3186 }
3187
3188 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
3189 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
3190 number of alternatives as this should be checked elsewhere. */
3191
3192 static int
3193 count_alternatives (rtx exp)
3194 {
3195 int i, j, n;
3196 const char *fmt;
3197
3198 if (GET_CODE (exp) == MATCH_OPERAND)
3199 return n_comma_elts (XSTR (exp, 2));
3200
3201 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
3202 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
3203 switch (*fmt++)
3204 {
3205 case 'e':
3206 case 'u':
3207 n = count_alternatives (XEXP (exp, i));
3208 if (n)
3209 return n;
3210 break;
3211
3212 case 'E':
3213 case 'V':
3214 if (XVEC (exp, i) != NULL)
3215 for (j = 0; j < XVECLEN (exp, i); j++)
3216 {
3217 n = count_alternatives (XVECEXP (exp, i, j));
3218 if (n)
3219 return n;
3220 }
3221 }
3222
3223 return 0;
3224 }
3225
3226 /* Returns nonzero if the given expression contains an EQ_ATTR with the
3227 `alternative' attribute. */
3228
3229 static int
3230 compares_alternatives_p (rtx exp)
3231 {
3232 int i, j;
3233 const char *fmt;
3234
3235 if (GET_CODE (exp) == EQ_ATTR && XSTR (exp, 0) == alternative_name)
3236 return 1;
3237
3238 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
3239 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
3240 switch (*fmt++)
3241 {
3242 case 'e':
3243 case 'u':
3244 if (compares_alternatives_p (XEXP (exp, i)))
3245 return 1;
3246 break;
3247
3248 case 'E':
3249 for (j = 0; j < XVECLEN (exp, i); j++)
3250 if (compares_alternatives_p (XVECEXP (exp, i, j)))
3251 return 1;
3252 break;
3253 }
3254
3255 return 0;
3256 }
3257
3258 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
3259
3260 static void
3261 gen_insn (rtx exp, int lineno)
3262 {
3263 struct insn_def *id;
3264
3265 id = oballoc (struct insn_def);
3266 id->next = defs;
3267 defs = id;
3268 id->def = exp;
3269 id->loc = file_location (read_md_filename, lineno);
3270
3271 switch (GET_CODE (exp))
3272 {
3273 case DEFINE_INSN:
3274 id->insn_code = insn_code_number;
3275 id->insn_index = insn_index_number;
3276 id->num_alternatives = count_alternatives (exp);
3277 if (id->num_alternatives == 0)
3278 id->num_alternatives = 1;
3279 id->vec_idx = 4;
3280 break;
3281
3282 case DEFINE_PEEPHOLE:
3283 id->insn_code = insn_code_number;
3284 id->insn_index = insn_index_number;
3285 id->num_alternatives = count_alternatives (exp);
3286 if (id->num_alternatives == 0)
3287 id->num_alternatives = 1;
3288 id->vec_idx = 3;
3289 break;
3290
3291 case DEFINE_ASM_ATTRIBUTES:
3292 id->insn_code = -1;
3293 id->insn_index = -1;
3294 id->num_alternatives = 1;
3295 id->vec_idx = 0;
3296 got_define_asm_attributes = 1;
3297 break;
3298
3299 default:
3300 gcc_unreachable ();
3301 }
3302 }
3303
3304 /* Process a DEFINE_DELAY. Validate the vector length, check if annul
3305 true or annul false is specified, and make a `struct delay_desc'. */
3306
3307 static void
3308 gen_delay (rtx def, int lineno)
3309 {
3310 struct delay_desc *delay;
3311 int i;
3312
3313 if (XVECLEN (def, 1) % 3 != 0)
3314 {
3315 error_with_line (lineno,
3316 "number of elements in DEFINE_DELAY must"
3317 " be multiple of three");
3318 return;
3319 }
3320
3321 for (i = 0; i < XVECLEN (def, 1); i += 3)
3322 {
3323 if (XVECEXP (def, 1, i + 1))
3324 have_annul_true = 1;
3325 if (XVECEXP (def, 1, i + 2))
3326 have_annul_false = 1;
3327 }
3328
3329 delay = oballoc (struct delay_desc);
3330 delay->def = def;
3331 delay->num = ++num_delays;
3332 delay->next = delays;
3333 delay->loc = file_location (read_md_filename, lineno);
3334 delays = delay;
3335 }
3336
3337 /* Names of attributes that could be possibly cached. */
3338 static const char *cached_attrs[32];
3339 /* Number of such attributes. */
3340 static int cached_attr_count;
3341 /* Bitmasks of possibly cached attributes. */
3342 static unsigned int attrs_seen_once, attrs_seen_more_than_once;
3343 static unsigned int attrs_to_cache;
3344 static unsigned int attrs_cached_inside, attrs_cached_after;
3345
3346 /* Finds non-const attributes that could be possibly cached.
3347 When create is TRUE, fills in cached_attrs array.
3348 Computes ATTRS_SEEN_ONCE and ATTRS_SEEN_MORE_THAN_ONCE
3349 bitmasks. */
3350
3351 static void
3352 find_attrs_to_cache (rtx exp, bool create)
3353 {
3354 int i;
3355 const char *name;
3356 struct attr_desc *attr;
3357
3358 if (exp == NULL)
3359 return;
3360
3361 switch (GET_CODE (exp))
3362 {
3363 case NOT:
3364 if (GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
3365 find_attrs_to_cache (XEXP (exp, 0), create);
3366 return;
3367
3368 case EQ_ATTR:
3369 name = XSTR (exp, 0);
3370 if (name == alternative_name)
3371 return;
3372 for (i = 0; i < cached_attr_count; i++)
3373 if (name == cached_attrs[i])
3374 {
3375 if ((attrs_seen_once & (1U << i)) != 0)
3376 attrs_seen_more_than_once |= (1U << i);
3377 else
3378 attrs_seen_once |= (1U << i);
3379 return;
3380 }
3381 if (!create)
3382 return;
3383 attr = find_attr (&name, 0);
3384 gcc_assert (attr);
3385 if (attr->is_const)
3386 return;
3387 if (cached_attr_count == 32)
3388 return;
3389 cached_attrs[cached_attr_count] = XSTR (exp, 0);
3390 attrs_seen_once |= (1U << cached_attr_count);
3391 cached_attr_count++;
3392 return;
3393
3394 case AND:
3395 case IOR:
3396 find_attrs_to_cache (XEXP (exp, 0), create);
3397 find_attrs_to_cache (XEXP (exp, 1), create);
3398 return;
3399
3400 case COND:
3401 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3402 find_attrs_to_cache (XVECEXP (exp, 0, i), create);
3403 return;
3404
3405 default:
3406 return;
3407 }
3408 }
3409
3410 /* Given a piece of RTX, print a C expression to test its truth value to OUTF.
3411 We use AND and IOR both for logical and bit-wise operations, so
3412 interpret them as logical unless they are inside a comparison expression. */
3413
3414 /* Interpret AND/IOR as bit-wise operations instead of logical. */
3415 #define FLG_BITWISE 1
3416 /* Set if cached attribute will be known initialized in else block after
3417 this condition. This is true for LHS of toplevel && and || and
3418 even for RHS of ||, but not for RHS of &&. */
3419 #define FLG_AFTER 2
3420 /* Set if cached attribute will be known initialized in then block after
3421 this condition. This is true for LHS of toplevel && and || and
3422 even for RHS of &&, but not for RHS of ||. */
3423 #define FLG_INSIDE 4
3424 /* Cleared when an operand of &&. */
3425 #define FLG_OUTSIDE_AND 8
3426
3427 static unsigned int
3428 write_test_expr (FILE *outf, rtx exp, unsigned int attrs_cached, int flags)
3429 {
3430 int comparison_operator = 0;
3431 RTX_CODE code;
3432 struct attr_desc *attr;
3433
3434 /* In order not to worry about operator precedence, surround our part of
3435 the expression with parentheses. */
3436
3437 fprintf (outf, "(");
3438 code = GET_CODE (exp);
3439 switch (code)
3440 {
3441 /* Binary operators. */
3442 case GEU: case GTU:
3443 case LEU: case LTU:
3444 fprintf (outf, "(unsigned) ");
3445 /* Fall through. */
3446
3447 case EQ: case NE:
3448 case GE: case GT:
3449 case LE: case LT:
3450 comparison_operator = FLG_BITWISE;
3451
3452 case PLUS: case MINUS: case MULT: case DIV: case MOD:
3453 case AND: case IOR: case XOR:
3454 case ASHIFT: case LSHIFTRT: case ASHIFTRT:
3455 if ((code != AND && code != IOR) || (flags & FLG_BITWISE))
3456 {
3457 flags &= ~(FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND);
3458 write_test_expr (outf, XEXP (exp, 0), attrs_cached,
3459 flags | comparison_operator);
3460 }
3461 else
3462 {
3463 if (code == AND)
3464 flags &= ~FLG_OUTSIDE_AND;
3465 if (GET_CODE (XEXP (exp, 0)) == code
3466 || GET_CODE (XEXP (exp, 0)) == EQ_ATTR
3467 || (GET_CODE (XEXP (exp, 0)) == NOT
3468 && GET_CODE (XEXP (XEXP (exp, 0), 0)) == EQ_ATTR))
3469 attrs_cached
3470 = write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags);
3471 else
3472 write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags);
3473 }
3474 switch (code)
3475 {
3476 case EQ:
3477 fprintf (outf, " == ");
3478 break;
3479 case NE:
3480 fprintf (outf, " != ");
3481 break;
3482 case GE:
3483 fprintf (outf, " >= ");
3484 break;
3485 case GT:
3486 fprintf (outf, " > ");
3487 break;
3488 case GEU:
3489 fprintf (outf, " >= (unsigned) ");
3490 break;
3491 case GTU:
3492 fprintf (outf, " > (unsigned) ");
3493 break;
3494 case LE:
3495 fprintf (outf, " <= ");
3496 break;
3497 case LT:
3498 fprintf (outf, " < ");
3499 break;
3500 case LEU:
3501 fprintf (outf, " <= (unsigned) ");
3502 break;
3503 case LTU:
3504 fprintf (outf, " < (unsigned) ");
3505 break;
3506 case PLUS:
3507 fprintf (outf, " + ");
3508 break;
3509 case MINUS:
3510 fprintf (outf, " - ");
3511 break;
3512 case MULT:
3513 fprintf (outf, " * ");
3514 break;
3515 case DIV:
3516 fprintf (outf, " / ");
3517 break;
3518 case MOD:
3519 fprintf (outf, " %% ");
3520 break;
3521 case AND:
3522 if (flags & FLG_BITWISE)
3523 fprintf (outf, " & ");
3524 else
3525 fprintf (outf, " && ");
3526 break;
3527 case IOR:
3528 if (flags & FLG_BITWISE)
3529 fprintf (outf, " | ");
3530 else
3531 fprintf (outf, " || ");
3532 break;
3533 case XOR:
3534 fprintf (outf, " ^ ");
3535 break;
3536 case ASHIFT:
3537 fprintf (outf, " << ");
3538 break;
3539 case LSHIFTRT:
3540 case ASHIFTRT:
3541 fprintf (outf, " >> ");
3542 break;
3543 default:
3544 gcc_unreachable ();
3545 }
3546
3547 if (code == AND)
3548 {
3549 /* For if (something && (cached_x = get_attr_x (insn)) == X)
3550 cached_x is only known to be initialized in then block. */
3551 flags &= ~FLG_AFTER;
3552 }
3553 else if (code == IOR)
3554 {
3555 if (flags & FLG_OUTSIDE_AND)
3556 /* For if (something || (cached_x = get_attr_x (insn)) == X)
3557 cached_x is only known to be initialized in else block
3558 and else if conditions. */
3559 flags &= ~FLG_INSIDE;
3560 else
3561 /* For if ((something || (cached_x = get_attr_x (insn)) == X)
3562 && something_else)
3563 cached_x is not know to be initialized anywhere. */
3564 flags &= ~(FLG_AFTER | FLG_INSIDE);
3565 }
3566 if ((code == AND || code == IOR)
3567 && (GET_CODE (XEXP (exp, 1)) == code
3568 || GET_CODE (XEXP (exp, 1)) == EQ_ATTR
3569 || (GET_CODE (XEXP (exp, 1)) == NOT
3570 && GET_CODE (XEXP (XEXP (exp, 1), 0)) == EQ_ATTR)))
3571 attrs_cached
3572 = write_test_expr (outf, XEXP (exp, 1), attrs_cached, flags);
3573 else
3574 write_test_expr (outf, XEXP (exp, 1), attrs_cached,
3575 flags | comparison_operator);
3576 break;
3577
3578 case NOT:
3579 /* Special-case (not (eq_attrq "alternative" "x")) */
3580 if (! (flags & FLG_BITWISE) && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
3581 {
3582 if (XSTR (XEXP (exp, 0), 0) == alternative_name)
3583 {
3584 fprintf (outf, "which_alternative != %s",
3585 XSTR (XEXP (exp, 0), 1));
3586 break;
3587 }
3588
3589 fprintf (outf, "! ");
3590 attrs_cached =
3591 write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags);
3592 break;
3593 }
3594
3595 /* Otherwise, fall through to normal unary operator. */
3596
3597 /* Unary operators. */
3598 case ABS: case NEG:
3599 switch (code)
3600 {
3601 case NOT:
3602 if (flags & FLG_BITWISE)
3603 fprintf (outf, "~ ");
3604 else
3605 fprintf (outf, "! ");
3606 break;
3607 case ABS:
3608 fprintf (outf, "abs ");
3609 break;
3610 case NEG:
3611 fprintf (outf, "-");
3612 break;
3613 default:
3614 gcc_unreachable ();
3615 }
3616
3617 flags &= ~(FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND);
3618 write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags);
3619 break;
3620
3621 case EQ_ATTR_ALT:
3622 {
3623 int set = XINT (exp, 0), bit = 0;
3624
3625 if (flags & FLG_BITWISE)
3626 fatal ("EQ_ATTR_ALT not valid inside comparison");
3627
3628 if (!set)
3629 fatal ("Empty EQ_ATTR_ALT should be optimized out");
3630
3631 if (!(set & (set - 1)))
3632 {
3633 if (!(set & 0xffff))
3634 {
3635 bit += 16;
3636 set >>= 16;
3637 }
3638 if (!(set & 0xff))
3639 {
3640 bit += 8;
3641 set >>= 8;
3642 }
3643 if (!(set & 0xf))
3644 {
3645 bit += 4;
3646 set >>= 4;
3647 }
3648 if (!(set & 0x3))
3649 {
3650 bit += 2;
3651 set >>= 2;
3652 }
3653 if (!(set & 1))
3654 bit++;
3655
3656 fprintf (outf, "which_alternative %s= %d",
3657 XINT (exp, 1) ? "!" : "=", bit);
3658 }
3659 else
3660 {
3661 fprintf (outf, "%s((1 << which_alternative) & %#x)",
3662 XINT (exp, 1) ? "!" : "", set);
3663 }
3664 }
3665 break;
3666
3667 /* Comparison test of an attribute with a value. Most of these will
3668 have been removed by optimization. Handle "alternative"
3669 specially and give error if EQ_ATTR present inside a comparison. */
3670 case EQ_ATTR:
3671 if (flags & FLG_BITWISE)
3672 fatal ("EQ_ATTR not valid inside comparison");
3673
3674 if (XSTR (exp, 0) == alternative_name)
3675 {
3676 fprintf (outf, "which_alternative == %s", XSTR (exp, 1));
3677 break;
3678 }
3679
3680 attr = find_attr (&XSTR (exp, 0), 0);
3681 gcc_assert (attr);
3682
3683 /* Now is the time to expand the value of a constant attribute. */
3684 if (attr->is_const)
3685 {
3686 write_test_expr (outf,
3687 evaluate_eq_attr (exp, attr,
3688 attr->default_val->value,
3689 -2, -2),
3690 attrs_cached, 0);
3691 }
3692 else
3693 {
3694 int i;
3695 for (i = 0; i < cached_attr_count; i++)
3696 if (attr->name == cached_attrs[i])
3697 break;
3698 if (i < cached_attr_count && (attrs_cached & (1U << i)) != 0)
3699 fprintf (outf, "cached_%s", attr->name);
3700 else if (i < cached_attr_count && (attrs_to_cache & (1U << i)) != 0)
3701 {
3702 fprintf (outf, "(cached_%s = get_attr_%s (insn))",
3703 attr->name, attr->name);
3704 if (flags & FLG_AFTER)
3705 attrs_cached_after |= (1U << i);
3706 if (flags & FLG_INSIDE)
3707 attrs_cached_inside |= (1U << i);
3708 attrs_cached |= (1U << i);
3709 }
3710 else
3711 fprintf (outf, "get_attr_%s (insn)", attr->name);
3712 fprintf (outf, " == ");
3713 write_attr_valueq (outf, attr, XSTR (exp, 1));
3714 }
3715 break;
3716
3717 /* Comparison test of flags for define_delays. */
3718 case ATTR_FLAG:
3719 if (flags & FLG_BITWISE)
3720 fatal ("ATTR_FLAG not valid inside comparison");
3721 fprintf (outf, "(flags & ATTR_FLAG_%s) != 0", XSTR (exp, 0));
3722 break;
3723
3724 /* See if an operand matches a predicate. */
3725 case MATCH_OPERAND:
3726 /* If only a mode is given, just ensure the mode matches the operand.
3727 If neither a mode nor predicate is given, error. */
3728 if (XSTR (exp, 1) == NULL || *XSTR (exp, 1) == '\0')
3729 {
3730 if (GET_MODE (exp) == VOIDmode)
3731 fatal ("null MATCH_OPERAND specified as test");
3732 else
3733 fprintf (outf, "GET_MODE (operands[%d]) == %smode",
3734 XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
3735 }
3736 else
3737 fprintf (outf, "%s (operands[%d], %smode)",
3738 XSTR (exp, 1), XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
3739 break;
3740
3741 /* Constant integer. */
3742 case CONST_INT:
3743 fprintf (outf, HOST_WIDE_INT_PRINT_DEC, XWINT (exp, 0));
3744 break;
3745
3746 case MATCH_TEST:
3747 fprint_c_condition (outf, XSTR (exp, 0));
3748 if (flags & FLG_BITWISE)
3749 fprintf (outf, " != 0");
3750 break;
3751
3752 /* A random C expression. */
3753 case SYMBOL_REF:
3754 fprint_c_condition (outf, XSTR (exp, 0));
3755 break;
3756
3757 /* The address of the branch target. */
3758 case MATCH_DUP:
3759 fprintf (outf,
3760 "INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
3761 XINT (exp, 0), XINT (exp, 0), XINT (exp, 0));
3762 break;
3763
3764 case PC:
3765 /* The address of the current insn. We implement this actually as the
3766 address of the current insn for backward branches, but the last
3767 address of the next insn for forward branches, and both with
3768 adjustments that account for the worst-case possible stretching of
3769 intervening alignments between this insn and its destination. */
3770 fprintf (outf, "insn_current_reference_address (insn)");
3771 break;
3772
3773 case CONST_STRING:
3774 fprintf (outf, "%s", XSTR (exp, 0));
3775 break;
3776
3777 case IF_THEN_ELSE:
3778 write_test_expr (outf, XEXP (exp, 0), attrs_cached, 0);
3779 fprintf (outf, " ? ");
3780 write_test_expr (outf, XEXP (exp, 1), attrs_cached, FLG_BITWISE);
3781 fprintf (outf, " : ");
3782 write_test_expr (outf, XEXP (exp, 2), attrs_cached, FLG_BITWISE);
3783 break;
3784
3785 default:
3786 fatal ("bad RTX code `%s' in attribute calculation\n",
3787 GET_RTX_NAME (code));
3788 }
3789
3790 fprintf (outf, ")");
3791 return attrs_cached;
3792 }
3793
3794 /* Given an attribute value, return the maximum CONST_STRING argument
3795 encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */
3796
3797 static int
3798 max_attr_value (rtx exp, int *unknownp)
3799 {
3800 int current_max;
3801 int i, n;
3802
3803 switch (GET_CODE (exp))
3804 {
3805 case CONST_STRING:
3806 current_max = atoi (XSTR (exp, 0));
3807 break;
3808
3809 case COND:
3810 current_max = max_attr_value (XEXP (exp, 1), unknownp);
3811 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3812 {
3813 n = max_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
3814 if (n > current_max)
3815 current_max = n;
3816 }
3817 break;
3818
3819 case IF_THEN_ELSE:
3820 current_max = max_attr_value (XEXP (exp, 1), unknownp);
3821 n = max_attr_value (XEXP (exp, 2), unknownp);
3822 if (n > current_max)
3823 current_max = n;
3824 break;
3825
3826 default:
3827 *unknownp = 1;
3828 current_max = INT_MAX;
3829 break;
3830 }
3831
3832 return current_max;
3833 }
3834
3835 /* Given an attribute value, return the minimum CONST_STRING argument
3836 encountered. Set *UNKNOWNP and return 0 if the value is unknown. */
3837
3838 static int
3839 min_attr_value (rtx exp, int *unknownp)
3840 {
3841 int current_min;
3842 int i, n;
3843
3844 switch (GET_CODE (exp))
3845 {
3846 case CONST_STRING:
3847 current_min = atoi (XSTR (exp, 0));
3848 break;
3849
3850 case COND:
3851 current_min = min_attr_value (XEXP (exp, 1), unknownp);
3852 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3853 {
3854 n = min_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
3855 if (n < current_min)
3856 current_min = n;
3857 }
3858 break;
3859
3860 case IF_THEN_ELSE:
3861 current_min = min_attr_value (XEXP (exp, 1), unknownp);
3862 n = min_attr_value (XEXP (exp, 2), unknownp);
3863 if (n < current_min)
3864 current_min = n;
3865 break;
3866
3867 default:
3868 *unknownp = 1;
3869 current_min = INT_MAX;
3870 break;
3871 }
3872
3873 return current_min;
3874 }
3875
3876 /* Given an attribute value, return the result of ORing together all
3877 CONST_STRING arguments encountered. Set *UNKNOWNP and return -1
3878 if the numeric value is not known. */
3879
3880 static int
3881 or_attr_value (rtx exp, int *unknownp)
3882 {
3883 int current_or;
3884 int i;
3885
3886 switch (GET_CODE (exp))
3887 {
3888 case CONST_STRING:
3889 current_or = atoi (XSTR (exp, 0));
3890 break;
3891
3892 case COND:
3893 current_or = or_attr_value (XEXP (exp, 1), unknownp);
3894 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3895 current_or |= or_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
3896 break;
3897
3898 case IF_THEN_ELSE:
3899 current_or = or_attr_value (XEXP (exp, 1), unknownp);
3900 current_or |= or_attr_value (XEXP (exp, 2), unknownp);
3901 break;
3902
3903 default:
3904 *unknownp = 1;
3905 current_or = -1;
3906 break;
3907 }
3908
3909 return current_or;
3910 }
3911
3912 /* Scan an attribute value, possibly a conditional, and record what actions
3913 will be required to do any conditional tests in it.
3914
3915 Specifically, set
3916 `must_extract' if we need to extract the insn operands
3917 `must_constrain' if we must compute `which_alternative'
3918 `address_used' if an address expression was used
3919 `length_used' if an (eq_attr "length" ...) was used
3920 */
3921
3922 static void
3923 walk_attr_value (rtx exp)
3924 {
3925 int i, j;
3926 const char *fmt;
3927 RTX_CODE code;
3928
3929 if (exp == NULL)
3930 return;
3931
3932 code = GET_CODE (exp);
3933 switch (code)
3934 {
3935 case SYMBOL_REF:
3936 if (! ATTR_IND_SIMPLIFIED_P (exp))
3937 /* Since this is an arbitrary expression, it can look at anything.
3938 However, constant expressions do not depend on any particular
3939 insn. */
3940 must_extract = must_constrain = 1;
3941 return;
3942
3943 case MATCH_OPERAND:
3944 must_extract = 1;
3945 return;
3946
3947 case MATCH_TEST:
3948 case EQ_ATTR_ALT:
3949 must_extract = must_constrain = 1;
3950 break;
3951
3952 case EQ_ATTR:
3953 if (XSTR (exp, 0) == alternative_name)
3954 must_extract = must_constrain = 1;
3955 else if (strcmp_check (XSTR (exp, 0), length_str) == 0)
3956 length_used = 1;
3957 return;
3958
3959 case MATCH_DUP:
3960 must_extract = 1;
3961 address_used = 1;
3962 return;
3963
3964 case PC:
3965 address_used = 1;
3966 return;
3967
3968 case ATTR_FLAG:
3969 return;
3970
3971 default:
3972 break;
3973 }
3974
3975 for (i = 0, fmt = GET_RTX_FORMAT (code); i < GET_RTX_LENGTH (code); i++)
3976 switch (*fmt++)
3977 {
3978 case 'e':
3979 case 'u':
3980 walk_attr_value (XEXP (exp, i));
3981 break;
3982
3983 case 'E':
3984 if (XVEC (exp, i) != NULL)
3985 for (j = 0; j < XVECLEN (exp, i); j++)
3986 walk_attr_value (XVECEXP (exp, i, j));
3987 break;
3988 }
3989 }
3990
3991 /* Write out a function to obtain the attribute for a given INSN. */
3992
3993 static void
3994 write_attr_get (FILE *outf, struct attr_desc *attr)
3995 {
3996 struct attr_value *av, *common_av;
3997 int i, j;
3998
3999 /* Find the most used attribute value. Handle that as the `default' of the
4000 switch we will generate. */
4001 common_av = find_most_used (attr);
4002
4003 /* Write out start of function, then all values with explicit `case' lines,
4004 then a `default', then the value with the most uses. */
4005 if (attr->enum_name)
4006 fprintf (outf, "enum %s\n", attr->enum_name);
4007 else if (!attr->is_numeric)
4008 fprintf (outf, "enum attr_%s\n", attr->name);
4009 else
4010 fprintf (outf, "int\n");
4011
4012 /* If the attribute name starts with a star, the remainder is the name of
4013 the subroutine to use, instead of `get_attr_...'. */
4014 if (attr->name[0] == '*')
4015 fprintf (outf, "%s (rtx_insn *insn ATTRIBUTE_UNUSED)\n", &attr->name[1]);
4016 else if (attr->is_const == 0)
4017 fprintf (outf, "get_attr_%s (rtx_insn *insn ATTRIBUTE_UNUSED)\n", attr->name);
4018 else
4019 {
4020 fprintf (outf, "get_attr_%s (void)\n", attr->name);
4021 fprintf (outf, "{\n");
4022
4023 for (av = attr->first_value; av; av = av->next)
4024 if (av->num_insns == 1)
4025 write_attr_set (outf, attr, 2, av->value, "return", ";",
4026 true_rtx, av->first_insn->def->insn_code,
4027 av->first_insn->def->insn_index, 0);
4028 else if (av->num_insns != 0)
4029 write_attr_set (outf, attr, 2, av->value, "return", ";",
4030 true_rtx, -2, 0, 0);
4031
4032 fprintf (outf, "}\n\n");
4033 return;
4034 }
4035
4036 fprintf (outf, "{\n");
4037
4038 /* Find attributes that are worth caching in the conditions. */
4039 cached_attr_count = 0;
4040 attrs_seen_more_than_once = 0;
4041 for (av = attr->first_value; av; av = av->next)
4042 {
4043 attrs_seen_once = 0;
4044 find_attrs_to_cache (av->value, true);
4045 }
4046 /* Remove those that aren't worth caching from the array. */
4047 for (i = 0, j = 0; i < cached_attr_count; i++)
4048 if ((attrs_seen_more_than_once & (1U << i)) != 0)
4049 {
4050 const char *name = cached_attrs[i];
4051 struct attr_desc *cached_attr;
4052 if (i != j)
4053 cached_attrs[j] = name;
4054 cached_attr = find_attr (&name, 0);
4055 gcc_assert (cached_attr && cached_attr->is_const == 0);
4056 if (cached_attr->enum_name)
4057 fprintf (outf, " enum %s", cached_attr->enum_name);
4058 else if (!cached_attr->is_numeric)
4059 fprintf (outf, " enum attr_%s", cached_attr->name);
4060 else
4061 fprintf (outf, " int");
4062 fprintf (outf, " cached_%s ATTRIBUTE_UNUSED;\n", name);
4063 j++;
4064 }
4065 cached_attr_count = j;
4066 if (cached_attr_count)
4067 fprintf (outf, "\n");
4068
4069 fprintf (outf, " switch (recog_memoized (insn))\n");
4070 fprintf (outf, " {\n");
4071
4072 for (av = attr->first_value; av; av = av->next)
4073 if (av != common_av)
4074 write_attr_case (outf, attr, av, 1, "return", ";", 4, true_rtx);
4075
4076 write_attr_case (outf, attr, common_av, 0, "return", ";", 4, true_rtx);
4077 fprintf (outf, " }\n}\n\n");
4078 cached_attr_count = 0;
4079 }
4080
4081 /* Given an AND tree of known true terms (because we are inside an `if' with
4082 that as the condition or are in an `else' clause) and an expression,
4083 replace any known true terms with TRUE. Use `simplify_and_tree' to do
4084 the bulk of the work. */
4085
4086 static rtx
4087 eliminate_known_true (rtx known_true, rtx exp, int insn_code, int insn_index)
4088 {
4089 rtx term;
4090
4091 known_true = SIMPLIFY_TEST_EXP (known_true, insn_code, insn_index);
4092
4093 if (GET_CODE (known_true) == AND)
4094 {
4095 exp = eliminate_known_true (XEXP (known_true, 0), exp,
4096 insn_code, insn_index);
4097 exp = eliminate_known_true (XEXP (known_true, 1), exp,
4098 insn_code, insn_index);
4099 }
4100 else
4101 {
4102 term = known_true;
4103 exp = simplify_and_tree (exp, &term, insn_code, insn_index);
4104 }
4105
4106 return exp;
4107 }
4108
4109 /* Write out a series of tests and assignment statements to perform tests and
4110 sets of an attribute value. We are passed an indentation amount and prefix
4111 and suffix strings to write around each attribute value (e.g., "return"
4112 and ";"). */
4113
4114 static void
4115 write_attr_set (FILE *outf, struct attr_desc *attr, int indent, rtx value,
4116 const char *prefix, const char *suffix, rtx known_true,
4117 int insn_code, int insn_index, unsigned int attrs_cached)
4118 {
4119 if (GET_CODE (value) == COND)
4120 {
4121 /* Assume the default value will be the default of the COND unless we
4122 find an always true expression. */
4123 rtx default_val = XEXP (value, 1);
4124 rtx our_known_true = known_true;
4125 rtx newexp;
4126 int first_if = 1;
4127 int i;
4128
4129 if (cached_attr_count)
4130 {
4131 attrs_seen_once = 0;
4132 attrs_seen_more_than_once = 0;
4133 for (i = 0; i < XVECLEN (value, 0); i += 2)
4134 find_attrs_to_cache (XVECEXP (value, 0, i), false);
4135 attrs_to_cache |= attrs_seen_more_than_once;
4136 }
4137
4138 for (i = 0; i < XVECLEN (value, 0); i += 2)
4139 {
4140 rtx testexp;
4141 rtx inner_true;
4142
4143 /* Reset our_known_true after some time to not accumulate
4144 too much cruft (slowing down genattrtab). */
4145 if ((i & 31) == 0)
4146 our_known_true = known_true;
4147 testexp = eliminate_known_true (our_known_true,
4148 XVECEXP (value, 0, i),
4149 insn_code, insn_index);
4150 newexp = attr_rtx (NOT, testexp);
4151 newexp = insert_right_side (AND, our_known_true, newexp,
4152 insn_code, insn_index);
4153
4154 /* If the test expression is always true or if the next `known_true'
4155 expression is always false, this is the last case, so break
4156 out and let this value be the `else' case. */
4157 if (testexp == true_rtx || newexp == false_rtx)
4158 {
4159 default_val = XVECEXP (value, 0, i + 1);
4160 break;
4161 }
4162
4163 /* Compute the expression to pass to our recursive call as being
4164 known true. */
4165 inner_true = insert_right_side (AND, our_known_true,
4166 testexp, insn_code, insn_index);
4167
4168 /* If this is always false, skip it. */
4169 if (inner_true == false_rtx)
4170 continue;
4171
4172 attrs_cached_inside = attrs_cached;
4173 attrs_cached_after = attrs_cached;
4174 write_indent (outf, indent);
4175 fprintf (outf, "%sif ", first_if ? "" : "else ");
4176 first_if = 0;
4177 write_test_expr (outf, testexp, attrs_cached,
4178 (FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND));
4179 attrs_cached = attrs_cached_after;
4180 fprintf (outf, "\n");
4181 write_indent (outf, indent + 2);
4182 fprintf (outf, "{\n");
4183
4184 write_attr_set (outf, attr, indent + 4,
4185 XVECEXP (value, 0, i + 1), prefix, suffix,
4186 inner_true, insn_code, insn_index,
4187 attrs_cached_inside);
4188 write_indent (outf, indent + 2);
4189 fprintf (outf, "}\n");
4190 our_known_true = newexp;
4191 }
4192
4193 if (! first_if)
4194 {
4195 write_indent (outf, indent);
4196 fprintf (outf, "else\n");
4197 write_indent (outf, indent + 2);
4198 fprintf (outf, "{\n");
4199 }
4200
4201 write_attr_set (outf, attr, first_if ? indent : indent + 4, default_val,
4202 prefix, suffix, our_known_true, insn_code, insn_index,
4203 attrs_cached);
4204
4205 if (! first_if)
4206 {
4207 write_indent (outf, indent + 2);
4208 fprintf (outf, "}\n");
4209 }
4210 }
4211 else
4212 {
4213 write_indent (outf, indent);
4214 fprintf (outf, "%s ", prefix);
4215 write_attr_value (outf, attr, value);
4216 fprintf (outf, "%s\n", suffix);
4217 }
4218 }
4219
4220 /* Write a series of case statements for every instruction in list IE.
4221 INDENT is the amount of indentation to write before each case. */
4222
4223 static void
4224 write_insn_cases (FILE *outf, struct insn_ent *ie, int indent)
4225 {
4226 for (; ie != 0; ie = ie->next)
4227 if (ie->def->insn_code != -1)
4228 {
4229 write_indent (outf, indent);
4230 if (GET_CODE (ie->def->def) == DEFINE_PEEPHOLE)
4231 fprintf (outf, "case %d: /* define_peephole, %s:%d */\n",
4232 ie->def->insn_code, ie->def->loc.filename,
4233 ie->def->loc.lineno);
4234 else
4235 fprintf (outf, "case %d: /* %s */\n",
4236 ie->def->insn_code, XSTR (ie->def->def, 0));
4237 }
4238 }
4239
4240 /* Write out the computation for one attribute value. */
4241
4242 static void
4243 write_attr_case (FILE *outf, struct attr_desc *attr, struct attr_value *av,
4244 int write_case_lines, const char *prefix, const char *suffix,
4245 int indent, rtx known_true)
4246 {
4247 if (av->num_insns == 0)
4248 return;
4249
4250 if (av->has_asm_insn)
4251 {
4252 write_indent (outf, indent);
4253 fprintf (outf, "case -1:\n");
4254 write_indent (outf, indent + 2);
4255 fprintf (outf, "if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
4256 write_indent (outf, indent + 2);
4257 fprintf (outf, " && asm_noperands (PATTERN (insn)) < 0)\n");
4258 write_indent (outf, indent + 2);
4259 fprintf (outf, " fatal_insn_not_found (insn);\n");
4260 }
4261
4262 if (write_case_lines)
4263 write_insn_cases (outf, av->first_insn, indent);
4264 else
4265 {
4266 write_indent (outf, indent);
4267 fprintf (outf, "default:\n");
4268 }
4269
4270 /* See what we have to do to output this value. */
4271 must_extract = must_constrain = address_used = 0;
4272 walk_attr_value (av->value);
4273
4274 if (must_constrain)
4275 {
4276 write_indent (outf, indent + 2);
4277 fprintf (outf, "extract_constrain_insn_cached (insn);\n");
4278 }
4279 else if (must_extract)
4280 {
4281 write_indent (outf, indent + 2);
4282 fprintf (outf, "extract_insn_cached (insn);\n");
4283 }
4284
4285 attrs_to_cache = 0;
4286 if (av->num_insns == 1)
4287 write_attr_set (outf, attr, indent + 2, av->value, prefix, suffix,
4288 known_true, av->first_insn->def->insn_code,
4289 av->first_insn->def->insn_index, 0);
4290 else
4291 write_attr_set (outf, attr, indent + 2, av->value, prefix, suffix,
4292 known_true, -2, 0, 0);
4293
4294 if (strncmp (prefix, "return", 6))
4295 {
4296 write_indent (outf, indent + 2);
4297 fprintf (outf, "break;\n");
4298 }
4299 fprintf (outf, "\n");
4300 }
4301
4302 /* Utilities to write in various forms. */
4303
4304 static void
4305 write_attr_valueq (FILE *outf, struct attr_desc *attr, const char *s)
4306 {
4307 if (attr->is_numeric)
4308 {
4309 int num = atoi (s);
4310
4311 fprintf (outf, "%d", num);
4312
4313 if (num > 9 || num < 0)
4314 fprintf (outf, " /* %#x */", num);
4315 }
4316 else
4317 {
4318 write_upcase (outf, attr->enum_name ? attr->enum_name : attr->name);
4319 fprintf (outf, "_");
4320 write_upcase (outf, s);
4321 }
4322 }
4323
4324 static void
4325 write_attr_value (FILE *outf, struct attr_desc *attr, rtx value)
4326 {
4327 int op;
4328
4329 switch (GET_CODE (value))
4330 {
4331 case CONST_STRING:
4332 write_attr_valueq (outf, attr, XSTR (value, 0));
4333 break;
4334
4335 case CONST_INT:
4336 fprintf (outf, HOST_WIDE_INT_PRINT_DEC, INTVAL (value));
4337 break;
4338
4339 case SYMBOL_REF:
4340 fprint_c_condition (outf, XSTR (value, 0));
4341 break;
4342
4343 case ATTR:
4344 {
4345 struct attr_desc *attr2 = find_attr (&XSTR (value, 0), 0);
4346 if (attr->enum_name)
4347 fprintf (outf, "(enum %s)", attr->enum_name);
4348 else if (!attr->is_numeric)
4349 fprintf (outf, "(enum attr_%s)", attr->name);
4350 else if (!attr2->is_numeric)
4351 fprintf (outf, "(int)");
4352
4353 fprintf (outf, "get_attr_%s (%s)", attr2->name,
4354 (attr2->is_const ? "" : "insn"));
4355 }
4356 break;
4357
4358 case PLUS:
4359 op = '+';
4360 goto do_operator;
4361 case MINUS:
4362 op = '-';
4363 goto do_operator;
4364 case MULT:
4365 op = '*';
4366 goto do_operator;
4367 case DIV:
4368 op = '/';
4369 goto do_operator;
4370 case MOD:
4371 op = '%';
4372 goto do_operator;
4373
4374 do_operator:
4375 write_attr_value (outf, attr, XEXP (value, 0));
4376 fputc (' ', outf);
4377 fputc (op, outf);
4378 fputc (' ', outf);
4379 write_attr_value (outf, attr, XEXP (value, 1));
4380 break;
4381
4382 default:
4383 gcc_unreachable ();
4384 }
4385 }
4386
4387 static void
4388 write_upcase (FILE *outf, const char *str)
4389 {
4390 while (*str)
4391 {
4392 /* The argument of TOUPPER should not have side effects. */
4393 fputc (TOUPPER (*str), outf);
4394 str++;
4395 }
4396 }
4397
4398 static void
4399 write_indent (FILE *outf, int indent)
4400 {
4401 for (; indent > 8; indent -= 8)
4402 fprintf (outf, "\t");
4403
4404 for (; indent; indent--)
4405 fprintf (outf, " ");
4406 }
4407
4408 /* Write a subroutine that is given an insn that requires a delay slot, a
4409 delay slot ordinal, and a candidate insn. It returns nonzero if the
4410 candidate can be placed in the specified delay slot of the insn.
4411
4412 We can write as many as three subroutines. `eligible_for_delay'
4413 handles normal delay slots, `eligible_for_annul_true' indicates that
4414 the specified insn can be annulled if the branch is true, and likewise
4415 for `eligible_for_annul_false'.
4416
4417 KIND is a string distinguishing these three cases ("delay", "annul_true",
4418 or "annul_false"). */
4419
4420 static void
4421 write_eligible_delay (FILE *outf, const char *kind)
4422 {
4423 struct delay_desc *delay;
4424 int max_slots;
4425 char str[50];
4426 const char *pstr;
4427 struct attr_desc *attr;
4428 struct attr_value *av, *common_av;
4429 int i;
4430
4431 /* Compute the maximum number of delay slots required. We use the delay
4432 ordinal times this number plus one, plus the slot number as an index into
4433 the appropriate predicate to test. */
4434
4435 for (delay = delays, max_slots = 0; delay; delay = delay->next)
4436 if (XVECLEN (delay->def, 1) / 3 > max_slots)
4437 max_slots = XVECLEN (delay->def, 1) / 3;
4438
4439 /* Write function prelude. */
4440
4441 fprintf (outf, "int\n");
4442 fprintf (outf, "eligible_for_%s (rtx_insn *delay_insn ATTRIBUTE_UNUSED, int slot, \n"
4443 " rtx_insn *candidate_insn, int flags ATTRIBUTE_UNUSED)\n",
4444 kind);
4445 fprintf (outf, "{\n");
4446 fprintf (outf, " rtx_insn *insn;\n");
4447 fprintf (outf, "\n");
4448 fprintf (outf, " gcc_assert (slot < %d);\n", max_slots);
4449 fprintf (outf, "\n");
4450 /* Allow dbr_schedule to pass labels, etc. This can happen if try_split
4451 converts a compound instruction into a loop. */
4452 fprintf (outf, " if (!INSN_P (candidate_insn))\n");
4453 fprintf (outf, " return 0;\n");
4454 fprintf (outf, "\n");
4455
4456 /* If more than one delay type, find out which type the delay insn is. */
4457
4458 if (num_delays > 1)
4459 {
4460 attr = find_attr (&delay_type_str, 0);
4461 gcc_assert (attr);
4462 common_av = find_most_used (attr);
4463
4464 fprintf (outf, " insn = delay_insn;\n");
4465 fprintf (outf, " switch (recog_memoized (insn))\n");
4466 fprintf (outf, " {\n");
4467
4468 sprintf (str, " * %d;\n break;", max_slots);
4469 for (av = attr->first_value; av; av = av->next)
4470 if (av != common_av)
4471 write_attr_case (outf, attr, av, 1, "slot +=", str, 4, true_rtx);
4472
4473 write_attr_case (outf, attr, common_av, 0, "slot +=", str, 4, true_rtx);
4474 fprintf (outf, " }\n\n");
4475
4476 /* Ensure matched. Otherwise, shouldn't have been called. */
4477 fprintf (outf, " gcc_assert (slot >= %d);\n\n", max_slots);
4478 }
4479
4480 /* If just one type of delay slot, write simple switch. */
4481 if (num_delays == 1 && max_slots == 1)
4482 {
4483 fprintf (outf, " insn = candidate_insn;\n");
4484 fprintf (outf, " switch (recog_memoized (insn))\n");
4485 fprintf (outf, " {\n");
4486
4487 attr = find_attr (&delay_1_0_str, 0);
4488 gcc_assert (attr);
4489 common_av = find_most_used (attr);
4490
4491 for (av = attr->first_value; av; av = av->next)
4492 if (av != common_av)
4493 write_attr_case (outf, attr, av, 1, "return", ";", 4, true_rtx);
4494
4495 write_attr_case (outf, attr, common_av, 0, "return", ";", 4, true_rtx);
4496 fprintf (outf, " }\n");
4497 }
4498
4499 else
4500 {
4501 /* Write a nested CASE. The first indicates which condition we need to
4502 test, and the inner CASE tests the condition. */
4503 fprintf (outf, " insn = candidate_insn;\n");
4504 fprintf (outf, " switch (slot)\n");
4505 fprintf (outf, " {\n");
4506
4507 for (delay = delays; delay; delay = delay->next)
4508 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
4509 {
4510 fprintf (outf, " case %d:\n",
4511 (i / 3) + (num_delays == 1 ? 0 : delay->num * max_slots));
4512 fprintf (outf, " switch (recog_memoized (insn))\n");
4513 fprintf (outf, "\t{\n");
4514
4515 sprintf (str, "*%s_%d_%d", kind, delay->num, i / 3);
4516 pstr = str;
4517 attr = find_attr (&pstr, 0);
4518 gcc_assert (attr);
4519 common_av = find_most_used (attr);
4520
4521 for (av = attr->first_value; av; av = av->next)
4522 if (av != common_av)
4523 write_attr_case (outf, attr, av, 1, "return", ";", 8, true_rtx);
4524
4525 write_attr_case (outf, attr, common_av, 0, "return", ";", 8, true_rtx);
4526 fprintf (outf, " }\n");
4527 }
4528
4529 fprintf (outf, " default:\n");
4530 fprintf (outf, " gcc_unreachable ();\n");
4531 fprintf (outf, " }\n");
4532 }
4533
4534 fprintf (outf, "}\n\n");
4535 }
4536
4537 /* This page contains miscellaneous utility routines. */
4538
4539 /* Given a pointer to a (char *), return a malloc'ed string containing the
4540 next comma-separated element. Advance the pointer to after the string
4541 scanned, or the end-of-string. Return NULL if at end of string. */
4542
4543 static char *
4544 next_comma_elt (const char **pstr)
4545 {
4546 const char *start;
4547
4548 start = scan_comma_elt (pstr);
4549
4550 if (start == NULL)
4551 return NULL;
4552
4553 return attr_string (start, *pstr - start);
4554 }
4555
4556 /* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
4557 is nonzero, build a new attribute, if one does not exist. *NAME_P is
4558 replaced by a pointer to a canonical copy of the string. */
4559
4560 static struct attr_desc *
4561 find_attr (const char **name_p, int create)
4562 {
4563 struct attr_desc *attr;
4564 int index;
4565 const char *name = *name_p;
4566
4567 /* Before we resort to using `strcmp', see if the string address matches
4568 anywhere. In most cases, it should have been canonicalized to do so. */
4569 if (name == alternative_name)
4570 return NULL;
4571
4572 index = name[0] & (MAX_ATTRS_INDEX - 1);
4573 for (attr = attrs[index]; attr; attr = attr->next)
4574 if (name == attr->name)
4575 return attr;
4576
4577 /* Otherwise, do it the slow way. */
4578 for (attr = attrs[index]; attr; attr = attr->next)
4579 if (name[0] == attr->name[0] && ! strcmp (name, attr->name))
4580 {
4581 *name_p = attr->name;
4582 return attr;
4583 }
4584
4585 if (! create)
4586 return NULL;
4587
4588 attr = oballoc (struct attr_desc);
4589 attr->name = DEF_ATTR_STRING (name);
4590 attr->enum_name = 0;
4591 attr->first_value = attr->default_val = NULL;
4592 attr->is_numeric = attr->is_const = attr->is_special = 0;
4593 attr->next = attrs[index];
4594 attrs[index] = attr;
4595
4596 *name_p = attr->name;
4597
4598 return attr;
4599 }
4600
4601 /* Create internal attribute with the given default value. */
4602
4603 static void
4604 make_internal_attr (const char *name, rtx value, int special)
4605 {
4606 struct attr_desc *attr;
4607
4608 attr = find_attr (&name, 1);
4609 gcc_assert (!attr->default_val);
4610
4611 attr->is_numeric = 1;
4612 attr->is_const = 0;
4613 attr->is_special = (special & ATTR_SPECIAL) != 0;
4614 attr->default_val = get_attr_value (value, attr, -2);
4615 }
4616
4617 /* Find the most used value of an attribute. */
4618
4619 static struct attr_value *
4620 find_most_used (struct attr_desc *attr)
4621 {
4622 struct attr_value *av;
4623 struct attr_value *most_used;
4624 int nuses;
4625
4626 most_used = NULL;
4627 nuses = -1;
4628
4629 for (av = attr->first_value; av; av = av->next)
4630 if (av->num_insns > nuses)
4631 nuses = av->num_insns, most_used = av;
4632
4633 return most_used;
4634 }
4635
4636 /* Return (attr_value "n") */
4637
4638 static rtx
4639 make_numeric_value (int n)
4640 {
4641 static rtx int_values[20];
4642 rtx exp;
4643 char *p;
4644
4645 gcc_assert (n >= 0);
4646
4647 if (n < 20 && int_values[n])
4648 return int_values[n];
4649
4650 p = attr_printf (MAX_DIGITS, "%d", n);
4651 exp = attr_rtx (CONST_STRING, p);
4652
4653 if (n < 20)
4654 int_values[n] = exp;
4655
4656 return exp;
4657 }
4658
4659 static rtx
4660 copy_rtx_unchanging (rtx orig)
4661 {
4662 if (ATTR_IND_SIMPLIFIED_P (orig) || ATTR_CURR_SIMPLIFIED_P (orig))
4663 return orig;
4664
4665 ATTR_CURR_SIMPLIFIED_P (orig) = 1;
4666 return orig;
4667 }
4668
4669 /* Determine if an insn has a constant number of delay slots, i.e., the
4670 number of delay slots is not a function of the length of the insn. */
4671
4672 static void
4673 write_const_num_delay_slots (FILE *outf)
4674 {
4675 struct attr_desc *attr = find_attr (&num_delay_slots_str, 0);
4676 struct attr_value *av;
4677
4678 if (attr)
4679 {
4680 fprintf (outf, "int\nconst_num_delay_slots (rtx_insn *insn)\n");
4681 fprintf (outf, "{\n");
4682 fprintf (outf, " switch (recog_memoized (insn))\n");
4683 fprintf (outf, " {\n");
4684
4685 for (av = attr->first_value; av; av = av->next)
4686 {
4687 length_used = 0;
4688 walk_attr_value (av->value);
4689 if (length_used)
4690 write_insn_cases (outf, av->first_insn, 4);
4691 }
4692
4693 fprintf (outf, " default:\n");
4694 fprintf (outf, " return 1;\n");
4695 fprintf (outf, " }\n}\n\n");
4696 }
4697 }
4698 \f
4699 /* Synthetic attributes used by insn-automata.c and the scheduler.
4700 These are primarily concerned with (define_insn_reservation)
4701 patterns. */
4702
4703 struct insn_reserv
4704 {
4705 struct insn_reserv *next;
4706
4707 const char *name;
4708 int default_latency;
4709 rtx condexp;
4710
4711 /* Sequence number of this insn. */
4712 int insn_num;
4713
4714 /* Whether a (define_bypass) construct names this insn in its
4715 output list. */
4716 bool bypassed;
4717 };
4718
4719 static struct insn_reserv *all_insn_reservs = 0;
4720 static struct insn_reserv **last_insn_reserv_p = &all_insn_reservs;
4721 static size_t n_insn_reservs;
4722
4723 /* Store information from a DEFINE_INSN_RESERVATION for future
4724 attribute generation. */
4725 static void
4726 gen_insn_reserv (rtx def, int lineno)
4727 {
4728 struct insn_reserv *decl = oballoc (struct insn_reserv);
4729 file_location loc (read_md_filename, lineno);
4730
4731 decl->name = DEF_ATTR_STRING (XSTR (def, 0));
4732 decl->default_latency = XINT (def, 1);
4733 decl->condexp = check_attr_test (XEXP (def, 2), 0, loc);
4734 decl->insn_num = n_insn_reservs;
4735 decl->bypassed = false;
4736 decl->next = 0;
4737
4738 *last_insn_reserv_p = decl;
4739 last_insn_reserv_p = &decl->next;
4740 n_insn_reservs++;
4741 }
4742
4743 /* Store information from a DEFINE_BYPASS for future attribute
4744 generation. The only thing we care about is the list of output
4745 insns, which will later be used to tag reservation structures with
4746 a 'bypassed' bit. */
4747
4748 struct bypass_list
4749 {
4750 struct bypass_list *next;
4751 const char *pattern;
4752 };
4753
4754 static struct bypass_list *all_bypasses;
4755 static size_t n_bypasses;
4756 static size_t n_bypassed;
4757
4758 static void
4759 gen_bypass_1 (const char *s, size_t len)
4760 {
4761 struct bypass_list *b;
4762
4763 if (len == 0)
4764 return;
4765
4766 s = attr_string (s, len);
4767 for (b = all_bypasses; b; b = b->next)
4768 if (s == b->pattern)
4769 return; /* already got that one */
4770
4771 b = oballoc (struct bypass_list);
4772 b->pattern = s;
4773 b->next = all_bypasses;
4774 all_bypasses = b;
4775 n_bypasses++;
4776 }
4777
4778 static void
4779 gen_bypass (rtx def)
4780 {
4781 const char *p, *base;
4782
4783 for (p = base = XSTR (def, 1); *p; p++)
4784 if (*p == ',')
4785 {
4786 gen_bypass_1 (base, p - base);
4787 do
4788 p++;
4789 while (ISSPACE (*p));
4790 base = p;
4791 }
4792 gen_bypass_1 (base, p - base);
4793 }
4794
4795 /* Find and mark all of the bypassed insns. */
4796 static void
4797 process_bypasses (void)
4798 {
4799 struct bypass_list *b;
4800 struct insn_reserv *r;
4801
4802 n_bypassed = 0;
4803
4804 /* The reservation list is likely to be much longer than the bypass
4805 list. */
4806 for (r = all_insn_reservs; r; r = r->next)
4807 for (b = all_bypasses; b; b = b->next)
4808 if (fnmatch (b->pattern, r->name, 0) == 0)
4809 {
4810 n_bypassed++;
4811 r->bypassed = true;
4812 break;
4813 }
4814 }
4815
4816 /* Check that attribute NAME is used in define_insn_reservation condition
4817 EXP. Return true if it is. */
4818 static bool
4819 check_tune_attr (const char *name, rtx exp)
4820 {
4821 switch (GET_CODE (exp))
4822 {
4823 case AND:
4824 if (check_tune_attr (name, XEXP (exp, 0)))
4825 return true;
4826 return check_tune_attr (name, XEXP (exp, 1));
4827
4828 case IOR:
4829 return (check_tune_attr (name, XEXP (exp, 0))
4830 && check_tune_attr (name, XEXP (exp, 1)));
4831
4832 case EQ_ATTR:
4833 return XSTR (exp, 0) == name;
4834
4835 default:
4836 return false;
4837 }
4838 }
4839
4840 /* Try to find a const attribute (usually cpu or tune) that is used
4841 in all define_insn_reservation conditions. */
4842 static struct attr_desc *
4843 find_tune_attr (rtx exp)
4844 {
4845 struct attr_desc *attr;
4846
4847 switch (GET_CODE (exp))
4848 {
4849 case AND:
4850 case IOR:
4851 attr = find_tune_attr (XEXP (exp, 0));
4852 if (attr)
4853 return attr;
4854 return find_tune_attr (XEXP (exp, 1));
4855
4856 case EQ_ATTR:
4857 if (XSTR (exp, 0) == alternative_name)
4858 return NULL;
4859
4860 attr = find_attr (&XSTR (exp, 0), 0);
4861 gcc_assert (attr);
4862
4863 if (attr->is_const && !attr->is_special)
4864 {
4865 struct insn_reserv *decl;
4866
4867 for (decl = all_insn_reservs; decl; decl = decl->next)
4868 if (! check_tune_attr (attr->name, decl->condexp))
4869 return NULL;
4870 return attr;
4871 }
4872 return NULL;
4873
4874 default:
4875 return NULL;
4876 }
4877 }
4878
4879 /* Create all of the attributes that describe automaton properties.
4880 Write the DFA and latency function prototypes to the files that
4881 need to have them, and write the init_sched_attrs(). */
4882
4883 static void
4884 make_automaton_attrs (void)
4885 {
4886 int i;
4887 struct insn_reserv *decl;
4888 rtx code_exp, lats_exp, byps_exp;
4889 struct attr_desc *tune_attr;
4890
4891 if (n_insn_reservs == 0)
4892 return;
4893
4894 tune_attr = find_tune_attr (all_insn_reservs->condexp);
4895 if (tune_attr != NULL)
4896 {
4897 rtx *condexps = XNEWVEC (rtx, n_insn_reservs * 3);
4898 struct attr_value *val;
4899 bool first = true;
4900
4901 gcc_assert (tune_attr->is_const
4902 && !tune_attr->is_special
4903 && !tune_attr->is_numeric);
4904
4905 /* Write the prototypes for all DFA functions. */
4906 for (val = tune_attr->first_value; val; val = val->next)
4907 {
4908 if (val == tune_attr->default_val)
4909 continue;
4910 gcc_assert (GET_CODE (val->value) == CONST_STRING);
4911 fprintf (dfa_file,
4912 "extern int internal_dfa_insn_code_%s (rtx_insn *);\n",
4913 XSTR (val->value, 0));
4914 }
4915 fprintf (dfa_file, "\n");
4916
4917 /* Write the prototypes for all latency functions. */
4918 for (val = tune_attr->first_value; val; val = val->next)
4919 {
4920 if (val == tune_attr->default_val)
4921 continue;
4922 gcc_assert (GET_CODE (val->value) == CONST_STRING);
4923 fprintf (latency_file,
4924 "extern int insn_default_latency_%s (rtx_insn *);\n",
4925 XSTR (val->value, 0));
4926 }
4927 fprintf (latency_file, "\n");
4928
4929 /* Write the prototypes for all automaton functions. */
4930 for (val = tune_attr->first_value; val; val = val->next)
4931 {
4932 if (val == tune_attr->default_val)
4933 continue;
4934 gcc_assert (GET_CODE (val->value) == CONST_STRING);
4935 fprintf (attr_file,
4936 "extern int internal_dfa_insn_code_%s (rtx_insn *);\n"
4937 "extern int insn_default_latency_%s (rtx_insn *);\n",
4938 XSTR (val->value, 0), XSTR (val->value, 0));
4939 }
4940 fprintf (attr_file, "\n");
4941 fprintf (attr_file, "int (*internal_dfa_insn_code) (rtx_insn *);\n");
4942 fprintf (attr_file, "int (*insn_default_latency) (rtx_insn *);\n");
4943 fprintf (attr_file, "\n");
4944 fprintf (attr_file, "void\n");
4945 fprintf (attr_file, "init_sched_attrs (void)\n");
4946 fprintf (attr_file, "{\n");
4947
4948 for (val = tune_attr->first_value; val; val = val->next)
4949 {
4950 int j;
4951 char *name;
4952 rtx test = attr_rtx (EQ_ATTR, tune_attr->name, XSTR (val->value, 0));
4953
4954 if (val == tune_attr->default_val)
4955 continue;
4956 for (decl = all_insn_reservs, i = 0;
4957 decl;
4958 decl = decl->next)
4959 {
4960 rtx ctest = test;
4961 rtx condexp
4962 = simplify_and_tree (decl->condexp, &ctest, -2, 0);
4963 if (condexp == false_rtx)
4964 continue;
4965 if (condexp == true_rtx)
4966 break;
4967 condexps[i] = condexp;
4968 condexps[i + 1] = make_numeric_value (decl->insn_num);
4969 condexps[i + 2] = make_numeric_value (decl->default_latency);
4970 i += 3;
4971 }
4972
4973 code_exp = rtx_alloc (COND);
4974 lats_exp = rtx_alloc (COND);
4975
4976 j = i / 3 * 2;
4977 XVEC (code_exp, 0) = rtvec_alloc (j);
4978 XVEC (lats_exp, 0) = rtvec_alloc (j);
4979
4980 if (decl)
4981 {
4982 XEXP (code_exp, 1) = make_numeric_value (decl->insn_num);
4983 XEXP (lats_exp, 1) = make_numeric_value (decl->default_latency);
4984 }
4985 else
4986 {
4987 XEXP (code_exp, 1) = make_numeric_value (n_insn_reservs + 1);
4988 XEXP (lats_exp, 1) = make_numeric_value (0);
4989 }
4990
4991 while (i > 0)
4992 {
4993 i -= 3;
4994 j -= 2;
4995 XVECEXP (code_exp, 0, j) = condexps[i];
4996 XVECEXP (lats_exp, 0, j) = condexps[i];
4997
4998 XVECEXP (code_exp, 0, j + 1) = condexps[i + 1];
4999 XVECEXP (lats_exp, 0, j + 1) = condexps[i + 2];
5000 }
5001
5002 name = XNEWVEC (char,
5003 sizeof ("*internal_dfa_insn_code_")
5004 + strlen (XSTR (val->value, 0)));
5005 strcpy (name, "*internal_dfa_insn_code_");
5006 strcat (name, XSTR (val->value, 0));
5007 make_internal_attr (name, code_exp, ATTR_NONE);
5008 strcpy (name, "*insn_default_latency_");
5009 strcat (name, XSTR (val->value, 0));
5010 make_internal_attr (name, lats_exp, ATTR_NONE);
5011 XDELETEVEC (name);
5012
5013 if (first)
5014 {
5015 fprintf (attr_file, " if (");
5016 first = false;
5017 }
5018 else
5019 fprintf (attr_file, " else if (");
5020 write_test_expr (attr_file, test, 0, 0);
5021 fprintf (attr_file, ")\n");
5022 fprintf (attr_file, " {\n");
5023 fprintf (attr_file, " internal_dfa_insn_code\n");
5024 fprintf (attr_file, " = internal_dfa_insn_code_%s;\n",
5025 XSTR (val->value, 0));
5026 fprintf (attr_file, " insn_default_latency\n");
5027 fprintf (attr_file, " = insn_default_latency_%s;\n",
5028 XSTR (val->value, 0));
5029 fprintf (attr_file, " }\n");
5030 }
5031
5032 fprintf (attr_file, " else\n");
5033 fprintf (attr_file, " gcc_unreachable ();\n");
5034 fprintf (attr_file, "}\n");
5035 fprintf (attr_file, "\n");
5036
5037 XDELETEVEC (condexps);
5038 }
5039 else
5040 {
5041 code_exp = rtx_alloc (COND);
5042 lats_exp = rtx_alloc (COND);
5043
5044 XVEC (code_exp, 0) = rtvec_alloc (n_insn_reservs * 2);
5045 XVEC (lats_exp, 0) = rtvec_alloc (n_insn_reservs * 2);
5046
5047 XEXP (code_exp, 1) = make_numeric_value (n_insn_reservs + 1);
5048 XEXP (lats_exp, 1) = make_numeric_value (0);
5049
5050 for (decl = all_insn_reservs, i = 0;
5051 decl;
5052 decl = decl->next, i += 2)
5053 {
5054 XVECEXP (code_exp, 0, i) = decl->condexp;
5055 XVECEXP (lats_exp, 0, i) = decl->condexp;
5056
5057 XVECEXP (code_exp, 0, i+1) = make_numeric_value (decl->insn_num);
5058 XVECEXP (lats_exp, 0, i+1)
5059 = make_numeric_value (decl->default_latency);
5060 }
5061 make_internal_attr ("*internal_dfa_insn_code", code_exp, ATTR_NONE);
5062 make_internal_attr ("*insn_default_latency", lats_exp, ATTR_NONE);
5063 }
5064
5065 if (n_bypasses == 0)
5066 byps_exp = make_numeric_value (0);
5067 else
5068 {
5069 process_bypasses ();
5070
5071 byps_exp = rtx_alloc (COND);
5072 XVEC (byps_exp, 0) = rtvec_alloc (n_bypassed * 2);
5073 XEXP (byps_exp, 1) = make_numeric_value (0);
5074 for (decl = all_insn_reservs, i = 0;
5075 decl;
5076 decl = decl->next)
5077 if (decl->bypassed)
5078 {
5079 XVECEXP (byps_exp, 0, i) = decl->condexp;
5080 XVECEXP (byps_exp, 0, i+1) = make_numeric_value (1);
5081 i += 2;
5082 }
5083 }
5084
5085 make_internal_attr ("*bypass_p", byps_exp, ATTR_NONE);
5086 }
5087
5088 static void
5089 write_header (FILE *outf)
5090 {
5091 fprintf (outf, "/* Generated automatically by the program `genattrtab'\n"
5092 " from the machine description file `md'. */\n\n");
5093
5094 fprintf (outf, "#include \"config.h\"\n");
5095 fprintf (outf, "#include \"system.h\"\n");
5096 fprintf (outf, "#include \"coretypes.h\"\n");
5097 fprintf (outf, "#include \"backend.h\"\n");
5098 fprintf (outf, "#include \"predict.h\"\n");
5099 fprintf (outf, "#include \"tree.h\"\n");
5100 fprintf (outf, "#include \"rtl.h\"\n");
5101 fprintf (outf, "#include \"alias.h\"\n");
5102 fprintf (outf, "#include \"options.h\"\n");
5103 fprintf (outf, "#include \"varasm.h\"\n");
5104 fprintf (outf, "#include \"stor-layout.h\"\n");
5105 fprintf (outf, "#include \"calls.h\"\n");
5106 fprintf (outf, "#include \"insn-attr.h\"\n");
5107 fprintf (outf, "#include \"tm_p.h\"\n");
5108 fprintf (outf, "#include \"insn-config.h\"\n");
5109 fprintf (outf, "#include \"recog.h\"\n");
5110 fprintf (outf, "#include \"regs.h\"\n");
5111 fprintf (outf, "#include \"real.h\"\n");
5112 fprintf (outf, "#include \"output.h\"\n");
5113 fprintf (outf, "#include \"toplev.h\"\n");
5114 fprintf (outf, "#include \"flags.h\"\n");
5115 fprintf (outf, "#include \"emit-rtl.h\"\n");
5116 fprintf (outf, "\n");
5117 fprintf (outf, "#define operands recog_data.operand\n\n");
5118 }
5119
5120 static FILE *
5121 open_outfile (const char *file_name)
5122 {
5123 FILE *outf;
5124 outf = fopen (file_name, "w");
5125 if (! outf)
5126 fatal ("cannot open file %s: %s", file_name, xstrerror (errno));
5127 write_header (outf);
5128 return outf;
5129 }
5130
5131 static bool
5132 handle_arg (const char *arg)
5133 {
5134 switch (arg[1])
5135 {
5136 case 'A':
5137 attr_file_name = &arg[2];
5138 return true;
5139 case 'D':
5140 dfa_file_name = &arg[2];
5141 return true;
5142 case 'L':
5143 latency_file_name = &arg[2];
5144 return true;
5145 default:
5146 return false;
5147 }
5148 }
5149
5150 int
5151 main (int argc, char **argv)
5152 {
5153 rtx desc;
5154 struct attr_desc *attr;
5155 struct insn_def *id;
5156 rtx tem;
5157 int i;
5158
5159 progname = "genattrtab";
5160
5161 if (!init_rtx_reader_args_cb (argc, argv, handle_arg))
5162 return FATAL_EXIT_CODE;
5163
5164 attr_file = open_outfile (attr_file_name);
5165 dfa_file = open_outfile (dfa_file_name);
5166 latency_file = open_outfile (latency_file_name);
5167
5168 obstack_init (hash_obstack);
5169 obstack_init (temp_obstack);
5170
5171 /* Set up true and false rtx's */
5172 true_rtx = rtx_alloc (CONST_INT);
5173 XWINT (true_rtx, 0) = 1;
5174 false_rtx = rtx_alloc (CONST_INT);
5175 XWINT (false_rtx, 0) = 0;
5176 ATTR_IND_SIMPLIFIED_P (true_rtx) = ATTR_IND_SIMPLIFIED_P (false_rtx) = 1;
5177 ATTR_PERMANENT_P (true_rtx) = ATTR_PERMANENT_P (false_rtx) = 1;
5178
5179 alternative_name = DEF_ATTR_STRING ("alternative");
5180 length_str = DEF_ATTR_STRING ("length");
5181 delay_type_str = DEF_ATTR_STRING ("*delay_type");
5182 delay_1_0_str = DEF_ATTR_STRING ("*delay_1_0");
5183 num_delay_slots_str = DEF_ATTR_STRING ("*num_delay_slots");
5184
5185 /* Read the machine description. */
5186
5187 while (1)
5188 {
5189 int lineno;
5190
5191 desc = read_md_rtx (&lineno, &insn_code_number);
5192 if (desc == NULL)
5193 break;
5194
5195 switch (GET_CODE (desc))
5196 {
5197 case DEFINE_INSN:
5198 case DEFINE_PEEPHOLE:
5199 case DEFINE_ASM_ATTRIBUTES:
5200 gen_insn (desc, lineno);
5201 break;
5202
5203 case DEFINE_ATTR:
5204 case DEFINE_ENUM_ATTR:
5205 gen_attr (desc, lineno);
5206 break;
5207
5208 case DEFINE_DELAY:
5209 gen_delay (desc, lineno);
5210 break;
5211
5212 case DEFINE_INSN_RESERVATION:
5213 gen_insn_reserv (desc, lineno);
5214 break;
5215
5216 case DEFINE_BYPASS:
5217 gen_bypass (desc);
5218 break;
5219
5220 default:
5221 break;
5222 }
5223 if (GET_CODE (desc) != DEFINE_ASM_ATTRIBUTES)
5224 insn_index_number++;
5225 }
5226
5227 if (have_error)
5228 return FATAL_EXIT_CODE;
5229
5230 insn_code_number++;
5231
5232 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
5233 if (! got_define_asm_attributes)
5234 {
5235 tem = rtx_alloc (DEFINE_ASM_ATTRIBUTES);
5236 XVEC (tem, 0) = rtvec_alloc (0);
5237 gen_insn (tem, 0);
5238 }
5239
5240 /* Expand DEFINE_DELAY information into new attribute. */
5241 if (num_delays)
5242 expand_delays ();
5243
5244 /* Make `insn_alternatives'. */
5245 insn_alternatives = oballocvec (uint64_t, insn_code_number);
5246 for (id = defs; id; id = id->next)
5247 if (id->insn_code >= 0)
5248 insn_alternatives[id->insn_code]
5249 = (((uint64_t) 1) << id->num_alternatives) - 1;
5250
5251 /* Make `insn_n_alternatives'. */
5252 insn_n_alternatives = oballocvec (int, insn_code_number);
5253 for (id = defs; id; id = id->next)
5254 if (id->insn_code >= 0)
5255 insn_n_alternatives[id->insn_code] = id->num_alternatives;
5256
5257 /* Construct extra attributes for automata. */
5258 make_automaton_attrs ();
5259
5260 /* Prepare to write out attribute subroutines by checking everything stored
5261 away and building the attribute cases. */
5262
5263 check_defs ();
5264
5265 for (i = 0; i < MAX_ATTRS_INDEX; i++)
5266 for (attr = attrs[i]; attr; attr = attr->next)
5267 attr->default_val->value
5268 = check_attr_value (attr->default_val->value, attr);
5269
5270 if (have_error)
5271 return FATAL_EXIT_CODE;
5272
5273 for (i = 0; i < MAX_ATTRS_INDEX; i++)
5274 for (attr = attrs[i]; attr; attr = attr->next)
5275 fill_attr (attr);
5276
5277 /* Construct extra attributes for `length'. */
5278 make_length_attrs ();
5279
5280 /* Perform any possible optimizations to speed up compilation. */
5281 optimize_attrs ();
5282
5283 /* Now write out all the `gen_attr_...' routines. Do these before the
5284 special routines so that they get defined before they are used. */
5285
5286 for (i = 0; i < MAX_ATTRS_INDEX; i++)
5287 for (attr = attrs[i]; attr; attr = attr->next)
5288 {
5289 FILE *outf;
5290
5291 #define IS_ATTR_GROUP(X) (!strncmp (attr->name, X, strlen (X)))
5292 if (IS_ATTR_GROUP ("*internal_dfa_insn_code"))
5293 outf = dfa_file;
5294 else if (IS_ATTR_GROUP ("*insn_default_latency"))
5295 outf = latency_file;
5296 else
5297 outf = attr_file;
5298 #undef IS_ATTR_GROUP
5299
5300 if (! attr->is_special && ! attr->is_const)
5301 write_attr_get (outf, attr);
5302 }
5303
5304 /* Write out delay eligibility information, if DEFINE_DELAY present.
5305 (The function to compute the number of delay slots will be written
5306 below.) */
5307 if (num_delays)
5308 {
5309 write_eligible_delay (attr_file, "delay");
5310 if (have_annul_true)
5311 write_eligible_delay (attr_file, "annul_true");
5312 if (have_annul_false)
5313 write_eligible_delay (attr_file, "annul_false");
5314 }
5315
5316 /* Write out constant delay slot info. */
5317 write_const_num_delay_slots (attr_file);
5318
5319 write_length_unit_log (attr_file);
5320
5321 if (fclose (attr_file) != 0)
5322 fatal ("cannot close file %s: %s", attr_file_name, xstrerror (errno));
5323 if (fclose (dfa_file) != 0)
5324 fatal ("cannot close file %s: %s", dfa_file_name, xstrerror (errno));
5325 if (fclose (latency_file) != 0)
5326 fatal ("cannot close file %s: %s", latency_file_name, xstrerror (errno));
5327
5328 return SUCCESS_EXIT_CODE;
5329 }
5330