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