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