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