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