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