rtl.h (global_rtx_index): New enum.
[gcc.git] / gcc / genattrtab.c
1 /* Generate code from machine description to compute values of attributes.
2 Copyright (C) 1991, 93-98, 1999 Free Software Foundation, Inc.
3 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
4
5 This file is part of GNU CC.
6
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
21
22 /* This program handles insn attributes and the DEFINE_DELAY and
23 DEFINE_FUNCTION_UNIT definitions.
24
25 It produces a series of functions named `get_attr_...', one for each insn
26 attribute. Each of these is given the rtx for an insn and returns a member
27 of the enum for the attribute.
28
29 These subroutines have the form of a `switch' on the INSN_CODE (via
30 `recog_memoized'). Each case either returns a constant attribute value
31 or a value that depends on tests on other attributes, the form of
32 operands, or some random C expression (encoded with a SYMBOL_REF
33 expression).
34
35 If the attribute `alternative', or a random C expression is present,
36 `constrain_operands' is called. If either of these cases of a reference to
37 an operand is found, `extract_insn' is called.
38
39 The special attribute `length' is also recognized. For this operand,
40 expressions involving the address of an operand or the current insn,
41 (address (pc)), are valid. In this case, an initial pass is made to
42 set all lengths that do not depend on address. Those that do are set to
43 the maximum length. Then each insn that depends on an address is checked
44 and possibly has its length changed. The process repeats until no further
45 changed are made. The resulting lengths are saved for use by
46 `get_attr_length'.
47
48 A special form of DEFINE_ATTR, where the expression for default value is a
49 CONST expression, indicates an attribute that is constant for a given run
50 of the compiler. The subroutine generated for these attributes has no
51 parameters as it does not depend on any particular insn. Constant
52 attributes are typically used to specify which variety of processor is
53 used.
54
55 Internal attributes are defined to handle DEFINE_DELAY and
56 DEFINE_FUNCTION_UNIT. Special routines are output for these cases.
57
58 This program works by keeping a list of possible values for each attribute.
59 These include the basic attribute choices, default values for attribute, and
60 all derived quantities.
61
62 As the description file is read, the definition for each insn is saved in a
63 `struct insn_def'. When the file reading is complete, a `struct insn_ent'
64 is created for each insn and chained to the corresponding attribute value,
65 either that specified, or the default.
66
67 An optimization phase is then run. This simplifies expressions for each
68 insn. EQ_ATTR tests are resolved, whenever possible, to a test that
69 indicates when the attribute has the specified value for the insn. This
70 avoids recursive calls during compilation.
71
72 The strategy used when processing DEFINE_DELAY and DEFINE_FUNCTION_UNIT
73 definitions is to create arbitrarily complex expressions and have the
74 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' (RTX_UNCHANGING_P): This rtx is fully simplified
89 independent of the insn code.
90 `in_struct' (MEM_IN_STRUCT_P): This rtx is fully simplified
91 for the insn code currently being processed (see optimize_attrs).
92 `integrated' (RTX_INTEGRATED_P): This rtx is permanent and unique
93 (see attr_rtx).
94 `volatil' (MEM_VOLATILE_P): During simplify_by_exploding the value of an
95 EQ_ATTR rtx is true if !volatil and false if volatil. */
96
97
98 #include "hconfig.h"
99 #include "system.h"
100 #include "rtl.h"
101 #include "insn-config.h" /* For REGISTER_CONSTRAINTS */
102 #include "ggc.h"
103
104 #ifdef HAVE_SYS_RESOURCE_H
105 # include <sys/resource.h>
106 #endif
107
108 /* We must include obstack.h after <sys/time.h>, to avoid lossage with
109 /usr/include/sys/stdtypes.h on Sun OS 4.x. */
110 #include "obstack.h"
111 #include "errors.h"
112
113 static struct obstack obstack, obstack1, obstack2;
114 struct obstack *rtl_obstack = &obstack;
115 struct obstack *hash_obstack = &obstack1;
116 struct obstack *temp_obstack = &obstack2;
117
118 #define obstack_chunk_alloc xmalloc
119 #define obstack_chunk_free free
120
121 /* enough space to reserve for printing out ints */
122 #define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3)
123
124 /* Define structures used to record attributes and values. */
125
126 /* As each DEFINE_INSN, DEFINE_PEEPHOLE, or DEFINE_ASM_ATTRIBUTES is
127 encountered, we store all the relevant information into a
128 `struct insn_def'. This is done to allow attribute definitions to occur
129 anywhere in the file. */
130
131 struct insn_def
132 {
133 int insn_code; /* Instruction number. */
134 int insn_index; /* Expression numer in file, for errors. */
135 struct insn_def *next; /* Next insn in chain. */
136 rtx def; /* The DEFINE_... */
137 int num_alternatives; /* Number of alternatives. */
138 int vec_idx; /* Index of attribute vector in `def'. */
139 };
140
141 /* Once everything has been read in, we store in each attribute value a list
142 of insn codes that have that value. Here is the structure used for the
143 list. */
144
145 struct insn_ent
146 {
147 int insn_code; /* Instruction number. */
148 int insn_index; /* Index of definition in file */
149 struct insn_ent *next; /* Next in chain. */
150 };
151
152 /* Each value of an attribute (either constant or computed) is assigned a
153 structure which is used as the listhead of the insns that have that
154 value. */
155
156 struct attr_value
157 {
158 rtx value; /* Value of attribute. */
159 struct attr_value *next; /* Next attribute value in chain. */
160 struct insn_ent *first_insn; /* First insn with this value. */
161 int num_insns; /* Number of insns with this value. */
162 int has_asm_insn; /* True if this value used for `asm' insns */
163 };
164
165 /* Structure for each attribute. */
166
167 struct attr_desc
168 {
169 char *name; /* Name of attribute. */
170 struct attr_desc *next; /* Next attribute. */
171 unsigned is_numeric : 1; /* Values of this attribute are numeric. */
172 unsigned negative_ok : 1; /* Allow negative numeric values. */
173 unsigned unsigned_p : 1; /* Make the output function unsigned int. */
174 unsigned is_const : 1; /* Attribute value constant for each run. */
175 unsigned is_special : 1; /* Don't call `write_attr_set'. */
176 unsigned func_units_p : 1; /* this is the function_units attribute */
177 unsigned blockage_p : 1; /* this is the blockage range function */
178 struct attr_value *first_value; /* First value of this attribute. */
179 struct attr_value *default_val; /* Default value for this attribute. */
180 };
181
182 #define NULL_ATTR (struct attr_desc *) NULL
183
184 /* A range of values. */
185
186 struct range
187 {
188 int min;
189 int max;
190 };
191
192 /* Structure for each DEFINE_DELAY. */
193
194 struct delay_desc
195 {
196 rtx def; /* DEFINE_DELAY expression. */
197 struct delay_desc *next; /* Next DEFINE_DELAY. */
198 int num; /* Number of DEFINE_DELAY, starting at 1. */
199 };
200
201 /* Record information about each DEFINE_FUNCTION_UNIT. */
202
203 struct function_unit_op
204 {
205 rtx condexp; /* Expression TRUE for applicable insn. */
206 struct function_unit_op *next; /* Next operation for this function unit. */
207 int num; /* Ordinal for this operation type in unit. */
208 int ready; /* Cost until data is ready. */
209 int issue_delay; /* Cost until unit can accept another insn. */
210 rtx conflict_exp; /* Expression TRUE for insns incurring issue delay. */
211 rtx issue_exp; /* Expression computing issue delay. */
212 };
213
214 /* Record information about each function unit mentioned in a
215 DEFINE_FUNCTION_UNIT. */
216
217 struct function_unit
218 {
219 char *name; /* Function unit name. */
220 struct function_unit *next; /* Next function unit. */
221 int num; /* Ordinal of this unit type. */
222 int multiplicity; /* Number of units of this type. */
223 int simultaneity; /* Maximum number of simultaneous insns
224 on this function unit or 0 if unlimited. */
225 rtx condexp; /* Expression TRUE for insn needing unit. */
226 int num_opclasses; /* Number of different operation types. */
227 struct function_unit_op *ops; /* Pointer to first operation type. */
228 int needs_conflict_function; /* Nonzero if a conflict function required. */
229 int needs_blockage_function; /* Nonzero if a blockage function required. */
230 int needs_range_function; /* Nonzero if blockage range function needed.*/
231 rtx default_cost; /* Conflict cost, if constant. */
232 struct range issue_delay; /* Range of issue delay values. */
233 int max_blockage; /* Maximum time an insn blocks the unit. */
234 };
235
236 /* Listheads of above structures. */
237
238 /* This one is indexed by the first character of the attribute name. */
239 #define MAX_ATTRS_INDEX 256
240 static struct attr_desc *attrs[MAX_ATTRS_INDEX];
241 static struct insn_def *defs;
242 static struct delay_desc *delays;
243 static struct function_unit *units;
244
245 /* An expression where all the unknown terms are EQ_ATTR tests can be
246 rearranged into a COND provided we can enumerate all possible
247 combinations of the unknown values. The set of combinations become the
248 tests of the COND; the value of the expression given that combination is
249 computed and becomes the corresponding value. To do this, we must be
250 able to enumerate all values for each attribute used in the expression
251 (currently, we give up if we find a numeric attribute).
252
253 If the set of EQ_ATTR tests used in an expression tests the value of N
254 different attributes, the list of all possible combinations can be made
255 by walking the N-dimensional attribute space defined by those
256 attributes. We record each of these as a struct dimension.
257
258 The algorithm relies on sharing EQ_ATTR nodes: if two nodes in an
259 expression are the same, the will also have the same address. We find
260 all the EQ_ATTR nodes by marking them MEM_VOLATILE_P. This bit later
261 represents the value of an EQ_ATTR node, so once all nodes are marked,
262 they are also given an initial value of FALSE.
263
264 We then separate the set of EQ_ATTR nodes into dimensions for each
265 attribute and put them on the VALUES list. Terms are added as needed by
266 `add_values_to_cover' so that all possible values of the attribute are
267 tested.
268
269 Each dimension also has a current value. This is the node that is
270 currently considered to be TRUE. If this is one of the nodes added by
271 `add_values_to_cover', all the EQ_ATTR tests in the original expression
272 will be FALSE. Otherwise, only the CURRENT_VALUE will be true.
273
274 NUM_VALUES is simply the length of the VALUES list and is there for
275 convenience.
276
277 Once the dimensions are created, the algorithm enumerates all possible
278 values and computes the current value of the given expression. */
279
280 struct dimension
281 {
282 struct attr_desc *attr; /* Attribute for this dimension. */
283 rtx values; /* List of attribute values used. */
284 rtx current_value; /* Position in the list for the TRUE value. */
285 int num_values; /* Length of the values list. */
286 };
287
288 /* Other variables. */
289
290 static int insn_code_number;
291 static int insn_index_number;
292 static int got_define_asm_attributes;
293 static int must_extract;
294 static int must_constrain;
295 static int address_used;
296 static int length_used;
297 static int num_delays;
298 static int have_annul_true, have_annul_false;
299 static int num_units, num_unit_opclasses;
300 static int num_insn_ents;
301
302 /* Used as operand to `operate_exp': */
303
304 enum operator {PLUS_OP, MINUS_OP, POS_MINUS_OP, EQ_OP, OR_OP, ORX_OP, MAX_OP, MIN_OP, RANGE_OP};
305
306 /* Stores, for each insn code, the number of constraint alternatives. */
307
308 static int *insn_n_alternatives;
309
310 /* Stores, for each insn code, a bitmap that has bits on for each possible
311 alternative. */
312
313 static int *insn_alternatives;
314
315 /* If nonzero, assume that the `alternative' attr has this value.
316 This is the hashed, unique string for the numeral
317 whose value is chosen alternative. */
318
319 static char *current_alternative_string;
320
321 /* Used to simplify expressions. */
322
323 static rtx true_rtx, false_rtx;
324
325 /* Used to reduce calls to `strcmp' */
326
327 static char *alternative_name;
328
329 /* Indicate that REG_DEAD notes are valid if dead_or_set_p is ever
330 called. */
331
332 int reload_completed = 0;
333
334 /* Some machines test `optimize' in macros called from rtlanal.c, so we need
335 to define it here. */
336
337 int optimize = 0;
338
339 /* Simplify an expression. Only call the routine if there is something to
340 simplify. */
341 #define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX) \
342 (RTX_UNCHANGING_P (EXP) || MEM_IN_STRUCT_P (EXP) ? (EXP) \
343 : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
344
345 /* Simplify (eq_attr ("alternative") ...)
346 when we are working with a particular alternative. */
347 #define SIMPLIFY_ALTERNATIVE(EXP) \
348 if (current_alternative_string \
349 && GET_CODE ((EXP)) == EQ_ATTR \
350 && XSTR ((EXP), 0) == alternative_name) \
351 (EXP) = (XSTR ((EXP), 1) == current_alternative_string \
352 ? true_rtx : false_rtx);
353
354 /* These are referenced by rtlanal.c and hence need to be defined somewhere.
355 They won't actually be used. */
356
357 rtx global_rtl[GR_MAX];
358 rtx pic_offset_table_rtx;
359
360 static void attr_hash_add_rtx PROTO((int, rtx));
361 static void attr_hash_add_string PROTO((int, char *));
362 static rtx attr_rtx PVPROTO((enum rtx_code, ...));
363 static char *attr_printf PVPROTO((int, const char *, ...))
364 ATTRIBUTE_PRINTF_2;
365 static char *attr_string PROTO((const char *, int));
366 static rtx check_attr_test PROTO((rtx, int));
367 static rtx check_attr_value PROTO((rtx, struct attr_desc *));
368 static rtx convert_set_attr_alternative PROTO((rtx, int, int));
369 static rtx convert_set_attr PROTO((rtx, int, int));
370 static void check_defs PROTO((void));
371 #if 0
372 static rtx convert_const_symbol_ref PROTO((rtx, struct attr_desc *));
373 #endif
374 static rtx make_canonical PROTO((struct attr_desc *, rtx));
375 static struct attr_value *get_attr_value PROTO((rtx, struct attr_desc *, int));
376 static rtx copy_rtx_unchanging PROTO((rtx));
377 static rtx copy_boolean PROTO((rtx));
378 static void expand_delays PROTO((void));
379 static rtx operate_exp PROTO((enum operator, rtx, rtx));
380 static void expand_units PROTO((void));
381 static rtx simplify_knowing PROTO((rtx, rtx));
382 static rtx encode_units_mask PROTO((rtx));
383 static void fill_attr PROTO((struct attr_desc *));
384 /* dpx2 compiler chokes if we specify the arg types of the args. */
385 static rtx substitute_address PROTO((rtx, rtx (*) (rtx), rtx (*) (rtx)));
386 static void make_length_attrs PROTO((void));
387 static rtx identity_fn PROTO((rtx));
388 static rtx zero_fn PROTO((rtx));
389 static rtx one_fn PROTO((rtx));
390 static rtx max_fn PROTO((rtx));
391 static void write_length_unit_log PROTO ((void));
392 static rtx simplify_cond PROTO((rtx, int, int));
393 #if 0
394 static rtx simplify_by_alternatives PROTO((rtx, int, int));
395 #endif
396 static rtx simplify_by_exploding PROTO((rtx));
397 static int find_and_mark_used_attributes PROTO((rtx, rtx *, int *));
398 static void unmark_used_attributes PROTO((rtx, struct dimension *, int));
399 static int add_values_to_cover PROTO((struct dimension *));
400 static int increment_current_value PROTO((struct dimension *, int));
401 static rtx test_for_current_value PROTO((struct dimension *, int));
402 static rtx simplify_with_current_value PROTO((rtx, struct dimension *, int));
403 static rtx simplify_with_current_value_aux PROTO((rtx));
404 static void clear_struct_flag PROTO((rtx));
405 static int count_sub_rtxs PROTO((rtx, int));
406 static void remove_insn_ent PROTO((struct attr_value *, struct insn_ent *));
407 static void insert_insn_ent PROTO((struct attr_value *, struct insn_ent *));
408 static rtx insert_right_side PROTO((enum rtx_code, rtx, rtx, int, int));
409 static rtx make_alternative_compare PROTO((int));
410 static int compute_alternative_mask PROTO((rtx, enum rtx_code));
411 static rtx evaluate_eq_attr PROTO((rtx, rtx, int, int));
412 static rtx simplify_and_tree PROTO((rtx, rtx *, int, int));
413 static rtx simplify_or_tree PROTO((rtx, rtx *, int, int));
414 static rtx simplify_test_exp PROTO((rtx, int, int));
415 static void optimize_attrs PROTO((void));
416 static void gen_attr PROTO((rtx));
417 static int count_alternatives PROTO((rtx));
418 static int compares_alternatives_p PROTO((rtx));
419 static int contained_in_p PROTO((rtx, rtx));
420 static void gen_insn PROTO((rtx));
421 static void gen_delay PROTO((rtx));
422 static void gen_unit PROTO((rtx));
423 static void write_test_expr PROTO((rtx, int));
424 static int max_attr_value PROTO((rtx, int*));
425 static int or_attr_value PROTO((rtx, int*));
426 static void walk_attr_value PROTO((rtx));
427 static void write_attr_get PROTO((struct attr_desc *));
428 static rtx eliminate_known_true PROTO((rtx, rtx, int, int));
429 static void write_attr_set PROTO((struct attr_desc *, int, rtx,
430 const char *, const char *, rtx,
431 int, int));
432 static void write_attr_case PROTO((struct attr_desc *, struct attr_value *,
433 int, const char *, const char *, int, rtx));
434 static void write_unit_name PROTO((const char *, int, const char *));
435 static void write_attr_valueq PROTO((struct attr_desc *, char *));
436 static void write_attr_value PROTO((struct attr_desc *, rtx));
437 static void write_upcase PROTO((const char *));
438 static void write_indent PROTO((int));
439 static void write_eligible_delay PROTO((const char *));
440 static void write_function_unit_info PROTO((void));
441 static void write_complex_function PROTO((struct function_unit *, const char *,
442 const char *));
443 static int write_expr_attr_cache PROTO((rtx, struct attr_desc *));
444 static void write_toplevel_expr PROTO((rtx));
445 static void write_const_num_delay_slots PROTO ((void));
446 static int n_comma_elts PROTO((char *));
447 static char *next_comma_elt PROTO((char **));
448 static struct attr_desc *find_attr PROTO((const char *, int));
449 static void make_internal_attr PROTO((const char *, rtx, int));
450 static struct attr_value *find_most_used PROTO((struct attr_desc *));
451 static rtx find_single_value PROTO((struct attr_desc *));
452 static rtx make_numeric_value PROTO((int));
453 static void extend_range PROTO((struct range *, int, int));
454 static rtx attr_eq PROTO((char *, char *));
455 static char *attr_numeral PROTO((int));
456 static int attr_equal_p PROTO((rtx, rtx));
457 static rtx attr_copy_rtx PROTO((rtx));
458
459 #define oballoc(size) obstack_alloc (hash_obstack, size)
460
461 \f
462 /* Hash table for sharing RTL and strings. */
463
464 /* Each hash table slot is a bucket containing a chain of these structures.
465 Strings are given negative hash codes; RTL expressions are given positive
466 hash codes. */
467
468 struct attr_hash
469 {
470 struct attr_hash *next; /* Next structure in the bucket. */
471 int hashcode; /* Hash code of this rtx or string. */
472 union
473 {
474 char *str; /* The string (negative hash codes) */
475 rtx rtl; /* or the RTL recorded here. */
476 } u;
477 };
478
479 /* Now here is the hash table. When recording an RTL, it is added to
480 the slot whose index is the hash code mod the table size. Note
481 that the hash table is used for several kinds of RTL (see attr_rtx)
482 and for strings. While all these live in the same table, they are
483 completely independent, and the hash code is computed differently
484 for each. */
485
486 #define RTL_HASH_SIZE 4093
487 struct attr_hash *attr_hash_table[RTL_HASH_SIZE];
488
489 /* Here is how primitive or already-shared RTL's hash
490 codes are made. */
491 #define RTL_HASH(RTL) ((long) (RTL) & 0777777)
492
493 /* Add an entry to the hash table for RTL with hash code HASHCODE. */
494
495 static void
496 attr_hash_add_rtx (hashcode, rtl)
497 int hashcode;
498 rtx rtl;
499 {
500 register struct attr_hash *h;
501
502 h = (struct attr_hash *) obstack_alloc (hash_obstack,
503 sizeof (struct attr_hash));
504 h->hashcode = hashcode;
505 h->u.rtl = rtl;
506 h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
507 attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
508 }
509
510 /* Add an entry to the hash table for STRING with hash code HASHCODE. */
511
512 static void
513 attr_hash_add_string (hashcode, str)
514 int hashcode;
515 char *str;
516 {
517 register struct attr_hash *h;
518
519 h = (struct attr_hash *) obstack_alloc (hash_obstack,
520 sizeof (struct attr_hash));
521 h->hashcode = -hashcode;
522 h->u.str = str;
523 h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
524 attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
525 }
526
527 /* Generate an RTL expression, but avoid duplicates.
528 Set the RTX_INTEGRATED_P flag for these permanent objects.
529
530 In some cases we cannot uniquify; then we return an ordinary
531 impermanent rtx with RTX_INTEGRATED_P clear.
532
533 Args are like gen_rtx, but without the mode:
534
535 rtx attr_rtx (code, [element1, ..., elementn]) */
536
537 /*VARARGS1*/
538 static rtx
539 attr_rtx VPROTO((enum rtx_code code, ...))
540 {
541 #ifndef ANSI_PROTOTYPES
542 enum rtx_code code;
543 #endif
544 va_list p;
545 register int i; /* Array indices... */
546 register const char *fmt; /* Current rtx's format... */
547 register rtx rt_val; /* RTX to return to caller... */
548 int hashcode;
549 register struct attr_hash *h;
550 struct obstack *old_obstack = rtl_obstack;
551
552 VA_START (p, code);
553
554 #ifndef ANSI_PROTOTYPES
555 code = va_arg (p, enum rtx_code);
556 #endif
557
558 /* For each of several cases, search the hash table for an existing entry.
559 Use that entry if one is found; otherwise create a new RTL and add it
560 to the table. */
561
562 if (GET_RTX_CLASS (code) == '1')
563 {
564 rtx arg0 = va_arg (p, rtx);
565
566 /* A permanent object cannot point to impermanent ones. */
567 if (! RTX_INTEGRATED_P (arg0))
568 {
569 rt_val = rtx_alloc (code);
570 XEXP (rt_val, 0) = arg0;
571 va_end (p);
572 return rt_val;
573 }
574
575 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
576 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
577 if (h->hashcode == hashcode
578 && GET_CODE (h->u.rtl) == code
579 && XEXP (h->u.rtl, 0) == arg0)
580 goto found;
581
582 if (h == 0)
583 {
584 rtl_obstack = hash_obstack;
585 rt_val = rtx_alloc (code);
586 XEXP (rt_val, 0) = arg0;
587 }
588 }
589 else if (GET_RTX_CLASS (code) == 'c'
590 || GET_RTX_CLASS (code) == '2'
591 || GET_RTX_CLASS (code) == '<')
592 {
593 rtx arg0 = va_arg (p, rtx);
594 rtx arg1 = va_arg (p, rtx);
595
596 /* A permanent object cannot point to impermanent ones. */
597 if (! RTX_INTEGRATED_P (arg0) || ! RTX_INTEGRATED_P (arg1))
598 {
599 rt_val = rtx_alloc (code);
600 XEXP (rt_val, 0) = arg0;
601 XEXP (rt_val, 1) = arg1;
602 va_end (p);
603 return rt_val;
604 }
605
606 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
607 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
608 if (h->hashcode == hashcode
609 && GET_CODE (h->u.rtl) == code
610 && XEXP (h->u.rtl, 0) == arg0
611 && XEXP (h->u.rtl, 1) == arg1)
612 goto found;
613
614 if (h == 0)
615 {
616 rtl_obstack = hash_obstack;
617 rt_val = rtx_alloc (code);
618 XEXP (rt_val, 0) = arg0;
619 XEXP (rt_val, 1) = arg1;
620 }
621 }
622 else if (GET_RTX_LENGTH (code) == 1
623 && GET_RTX_FORMAT (code)[0] == 's')
624 {
625 char * arg0 = va_arg (p, char *);
626
627 if (code == SYMBOL_REF)
628 arg0 = attr_string (arg0, strlen (arg0));
629
630 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
631 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
632 if (h->hashcode == hashcode
633 && GET_CODE (h->u.rtl) == code
634 && XSTR (h->u.rtl, 0) == arg0)
635 goto found;
636
637 if (h == 0)
638 {
639 rtl_obstack = hash_obstack;
640 rt_val = rtx_alloc (code);
641 XSTR (rt_val, 0) = arg0;
642 }
643 }
644 else if (GET_RTX_LENGTH (code) == 2
645 && GET_RTX_FORMAT (code)[0] == 's'
646 && GET_RTX_FORMAT (code)[1] == 's')
647 {
648 char *arg0 = va_arg (p, char *);
649 char *arg1 = va_arg (p, char *);
650
651 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
652 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
653 if (h->hashcode == hashcode
654 && GET_CODE (h->u.rtl) == code
655 && XSTR (h->u.rtl, 0) == arg0
656 && XSTR (h->u.rtl, 1) == arg1)
657 goto found;
658
659 if (h == 0)
660 {
661 rtl_obstack = hash_obstack;
662 rt_val = rtx_alloc (code);
663 XSTR (rt_val, 0) = arg0;
664 XSTR (rt_val, 1) = arg1;
665 }
666 }
667 else if (code == CONST_INT)
668 {
669 HOST_WIDE_INT arg0 = va_arg (p, HOST_WIDE_INT);
670 if (arg0 == 0)
671 return false_rtx;
672 if (arg0 == 1)
673 return true_rtx;
674 goto nohash;
675 }
676 else
677 {
678 nohash:
679 rt_val = rtx_alloc (code); /* Allocate the storage space. */
680
681 fmt = GET_RTX_FORMAT (code); /* Find the right format... */
682 for (i = 0; i < GET_RTX_LENGTH (code); i++)
683 {
684 switch (*fmt++)
685 {
686 case '0': /* Unused field. */
687 break;
688
689 case 'i': /* An integer? */
690 XINT (rt_val, i) = va_arg (p, int);
691 break;
692
693 case 'w': /* A wide integer? */
694 XWINT (rt_val, i) = va_arg (p, HOST_WIDE_INT);
695 break;
696
697 case 's': /* A string? */
698 XSTR (rt_val, i) = va_arg (p, char *);
699 break;
700
701 case 'e': /* An expression? */
702 case 'u': /* An insn? Same except when printing. */
703 XEXP (rt_val, i) = va_arg (p, rtx);
704 break;
705
706 case 'E': /* An RTX vector? */
707 XVEC (rt_val, i) = va_arg (p, rtvec);
708 break;
709
710 default:
711 abort();
712 }
713 }
714 va_end (p);
715 return rt_val;
716 }
717
718 rtl_obstack = old_obstack;
719 va_end (p);
720 attr_hash_add_rtx (hashcode, rt_val);
721 RTX_INTEGRATED_P (rt_val) = 1;
722 return rt_val;
723
724 found:
725 va_end (p);
726 return h->u.rtl;
727 }
728
729 /* Create a new string printed with the printf line arguments into a space
730 of at most LEN bytes:
731
732 rtx attr_printf (len, format, [arg1, ..., argn]) */
733
734 /*VARARGS2*/
735 static char *
736 attr_printf VPROTO((register int len, const char *fmt, ...))
737 {
738 #ifndef ANSI_PROTOTYPES
739 register int len;
740 const char *fmt;
741 #endif
742 va_list p;
743 register char *str;
744
745 VA_START (p, fmt);
746
747 #ifndef ANSI_PROTOTYPES
748 len = va_arg (p, int);
749 fmt = va_arg (p, const char *);
750 #endif
751
752 /* Print the string into a temporary location. */
753 str = (char *) alloca (len);
754 vsprintf (str, fmt, p);
755 va_end (p);
756
757 return attr_string (str, strlen (str));
758 }
759
760 static rtx
761 attr_eq (name, value)
762 char *name, *value;
763 {
764 return attr_rtx (EQ_ATTR, attr_string (name, strlen (name)),
765 attr_string (value, strlen (value)));
766 }
767
768 static char *
769 attr_numeral (n)
770 int n;
771 {
772 return XSTR (make_numeric_value (n), 0);
773 }
774
775 /* Return a permanent (possibly shared) copy of a string STR (not assumed
776 to be null terminated) with LEN bytes. */
777
778 static char *
779 attr_string (str, len)
780 const char *str;
781 int len;
782 {
783 register struct attr_hash *h;
784 int hashcode;
785 int i;
786 register char *new_str;
787
788 /* Compute the hash code. */
789 hashcode = (len + 1) * 613 + (unsigned)str[0];
790 for (i = 1; i <= len; i += 2)
791 hashcode = ((hashcode * 613) + (unsigned)str[i]);
792 if (hashcode < 0)
793 hashcode = -hashcode;
794
795 /* Search the table for the string. */
796 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
797 if (h->hashcode == -hashcode && h->u.str[0] == str[0]
798 && !strncmp (h->u.str, str, len))
799 return h->u.str; /* <-- return if found. */
800
801 /* Not found; create a permanent copy and add it to the hash table. */
802 new_str = (char *) obstack_alloc (hash_obstack, len + 1);
803 bcopy (str, new_str, len);
804 new_str[len] = '\0';
805 attr_hash_add_string (hashcode, new_str);
806
807 return new_str; /* Return the new string. */
808 }
809
810 /* Check two rtx's for equality of contents,
811 taking advantage of the fact that if both are hashed
812 then they can't be equal unless they are the same object. */
813
814 static int
815 attr_equal_p (x, y)
816 rtx x, y;
817 {
818 return (x == y || (! (RTX_INTEGRATED_P (x) && RTX_INTEGRATED_P (y))
819 && rtx_equal_p (x, y)));
820 }
821 \f
822 /* Copy an attribute value expression,
823 descending to all depths, but not copying any
824 permanent hashed subexpressions. */
825
826 static rtx
827 attr_copy_rtx (orig)
828 register rtx orig;
829 {
830 register rtx copy;
831 register int i, j;
832 register RTX_CODE code;
833 register const char *format_ptr;
834
835 /* No need to copy a permanent object. */
836 if (RTX_INTEGRATED_P (orig))
837 return orig;
838
839 code = GET_CODE (orig);
840
841 switch (code)
842 {
843 case REG:
844 case QUEUED:
845 case CONST_INT:
846 case CONST_DOUBLE:
847 case SYMBOL_REF:
848 case CODE_LABEL:
849 case PC:
850 case CC0:
851 return orig;
852
853 default:
854 break;
855 }
856
857 copy = rtx_alloc (code);
858 PUT_MODE (copy, GET_MODE (orig));
859 copy->in_struct = orig->in_struct;
860 copy->volatil = orig->volatil;
861 copy->unchanging = orig->unchanging;
862 copy->integrated = orig->integrated;
863
864 format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
865
866 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
867 {
868 switch (*format_ptr++)
869 {
870 case 'e':
871 XEXP (copy, i) = XEXP (orig, i);
872 if (XEXP (orig, i) != NULL)
873 XEXP (copy, i) = attr_copy_rtx (XEXP (orig, i));
874 break;
875
876 case 'E':
877 case 'V':
878 XVEC (copy, i) = XVEC (orig, i);
879 if (XVEC (orig, i) != NULL)
880 {
881 XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
882 for (j = 0; j < XVECLEN (copy, i); j++)
883 XVECEXP (copy, i, j) = attr_copy_rtx (XVECEXP (orig, i, j));
884 }
885 break;
886
887 case 'n':
888 case 'i':
889 XINT (copy, i) = XINT (orig, i);
890 break;
891
892 case 'w':
893 XWINT (copy, i) = XWINT (orig, i);
894 break;
895
896 case 's':
897 case 'S':
898 XSTR (copy, i) = XSTR (orig, i);
899 break;
900
901 default:
902 abort ();
903 }
904 }
905 return copy;
906 }
907 \f
908 /* Given a test expression for an attribute, ensure it is validly formed.
909 IS_CONST indicates whether the expression is constant for each compiler
910 run (a constant expression may not test any particular insn).
911
912 Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
913 and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
914 test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
915
916 Update the string address in EQ_ATTR expression to be the same used
917 in the attribute (or `alternative_name') to speed up subsequent
918 `find_attr' calls and eliminate most `strcmp' calls.
919
920 Return the new expression, if any. */
921
922 static rtx
923 check_attr_test (exp, is_const)
924 rtx exp;
925 int is_const;
926 {
927 struct attr_desc *attr;
928 struct attr_value *av;
929 char *name_ptr, *p;
930 rtx orexp, newexp;
931
932 switch (GET_CODE (exp))
933 {
934 case EQ_ATTR:
935 /* Handle negation test. */
936 if (XSTR (exp, 1)[0] == '!')
937 return check_attr_test (attr_rtx (NOT,
938 attr_eq (XSTR (exp, 0),
939 &XSTR (exp, 1)[1])),
940 is_const);
941
942 else if (n_comma_elts (XSTR (exp, 1)) == 1)
943 {
944 attr = find_attr (XSTR (exp, 0), 0);
945 if (attr == NULL)
946 {
947 if (! strcmp (XSTR (exp, 0), "alternative"))
948 {
949 XSTR (exp, 0) = alternative_name;
950 /* This can't be simplified any further. */
951 RTX_UNCHANGING_P (exp) = 1;
952 return exp;
953 }
954 else
955 fatal ("Unknown attribute `%s' in EQ_ATTR", XSTR (exp, 0));
956 }
957
958 if (is_const && ! attr->is_const)
959 fatal ("Constant expression uses insn attribute `%s' in EQ_ATTR",
960 XSTR (exp, 0));
961
962 /* Copy this just to make it permanent,
963 so expressions using it can be permanent too. */
964 exp = attr_eq (XSTR (exp, 0), XSTR (exp, 1));
965
966 /* It shouldn't be possible to simplify the value given to a
967 constant attribute, so don't expand this until it's time to
968 write the test expression. */
969 if (attr->is_const)
970 RTX_UNCHANGING_P (exp) = 1;
971
972 if (attr->is_numeric)
973 {
974 for (p = XSTR (exp, 1); *p; p++)
975 if (*p < '0' || *p > '9')
976 fatal ("Attribute `%s' takes only numeric values",
977 XSTR (exp, 0));
978 }
979 else
980 {
981 for (av = attr->first_value; av; av = av->next)
982 if (GET_CODE (av->value) == CONST_STRING
983 && ! strcmp (XSTR (exp, 1), XSTR (av->value, 0)))
984 break;
985
986 if (av == NULL)
987 fatal ("Unknown value `%s' for `%s' attribute",
988 XSTR (exp, 1), XSTR (exp, 0));
989 }
990 }
991 else
992 {
993 /* Make an IOR tree of the possible values. */
994 orexp = false_rtx;
995 name_ptr = XSTR (exp, 1);
996 while ((p = next_comma_elt (&name_ptr)) != NULL)
997 {
998 newexp = attr_eq (XSTR (exp, 0), p);
999 orexp = insert_right_side (IOR, orexp, newexp, -2, -2);
1000 }
1001
1002 return check_attr_test (orexp, is_const);
1003 }
1004 break;
1005
1006 case ATTR_FLAG:
1007 break;
1008
1009 case CONST_INT:
1010 /* Either TRUE or FALSE. */
1011 if (XWINT (exp, 0))
1012 return true_rtx;
1013 else
1014 return false_rtx;
1015
1016 case IOR:
1017 case AND:
1018 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const);
1019 XEXP (exp, 1) = check_attr_test (XEXP (exp, 1), is_const);
1020 break;
1021
1022 case NOT:
1023 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const);
1024 break;
1025
1026 case MATCH_INSN:
1027 case MATCH_OPERAND:
1028 if (is_const)
1029 fatal ("RTL operator \"%s\" not valid in constant attribute test",
1030 GET_RTX_NAME (GET_CODE (exp)));
1031 /* These cases can't be simplified. */
1032 RTX_UNCHANGING_P (exp) = 1;
1033 break;
1034
1035 case LE: case LT: case GT: case GE:
1036 case LEU: case LTU: case GTU: case GEU:
1037 case NE: case EQ:
1038 if (GET_CODE (XEXP (exp, 0)) == SYMBOL_REF
1039 && GET_CODE (XEXP (exp, 1)) == SYMBOL_REF)
1040 exp = attr_rtx (GET_CODE (exp),
1041 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 0), 0)),
1042 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 1), 0)));
1043 /* These cases can't be simplified. */
1044 RTX_UNCHANGING_P (exp) = 1;
1045 break;
1046
1047 case SYMBOL_REF:
1048 if (is_const)
1049 {
1050 /* These cases are valid for constant attributes, but can't be
1051 simplified. */
1052 exp = attr_rtx (SYMBOL_REF, XSTR (exp, 0));
1053 RTX_UNCHANGING_P (exp) = 1;
1054 break;
1055 }
1056 default:
1057 fatal ("RTL operator \"%s\" not valid in attribute test",
1058 GET_RTX_NAME (GET_CODE (exp)));
1059 }
1060
1061 return exp;
1062 }
1063 \f
1064 /* Given an expression, ensure that it is validly formed and that all named
1065 attribute values are valid for the given attribute. Issue a fatal error
1066 if not. If no attribute is specified, assume a numeric attribute.
1067
1068 Return a perhaps modified replacement expression for the value. */
1069
1070 static rtx
1071 check_attr_value (exp, attr)
1072 rtx exp;
1073 struct attr_desc *attr;
1074 {
1075 struct attr_value *av;
1076 char *p;
1077 int i;
1078
1079 switch (GET_CODE (exp))
1080 {
1081 case CONST_INT:
1082 if (attr && ! attr->is_numeric)
1083 fatal ("CONST_INT not valid for non-numeric `%s' attribute",
1084 attr->name);
1085
1086 if (INTVAL (exp) < 0 && ! attr->negative_ok)
1087 fatal ("Negative numeric value specified for `%s' attribute",
1088 attr->name);
1089
1090 break;
1091
1092 case CONST_STRING:
1093 if (! strcmp (XSTR (exp, 0), "*"))
1094 break;
1095
1096 if (attr == 0 || attr->is_numeric)
1097 {
1098 p = XSTR (exp, 0);
1099 if (attr && attr->negative_ok && *p == '-')
1100 p++;
1101 for (; *p; p++)
1102 if (*p > '9' || *p < '0')
1103 fatal ("Non-numeric value for numeric `%s' attribute",
1104 attr ? attr->name : "internal");
1105 break;
1106 }
1107
1108 for (av = attr->first_value; av; av = av->next)
1109 if (GET_CODE (av->value) == CONST_STRING
1110 && ! strcmp (XSTR (av->value, 0), XSTR (exp, 0)))
1111 break;
1112
1113 if (av == NULL)
1114 fatal ("Unknown value `%s' for `%s' attribute",
1115 XSTR (exp, 0), attr ? attr->name : "internal");
1116
1117 break;
1118
1119 case IF_THEN_ELSE:
1120 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0),
1121 attr ? attr->is_const : 0);
1122 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1123 XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
1124 break;
1125
1126 case PLUS:
1127 case MINUS:
1128 case MULT:
1129 case DIV:
1130 case MOD:
1131 if (attr && !attr->is_numeric)
1132 fatal ("Invalid operation `%s' for non-numeric attribute value",
1133 GET_RTX_NAME (GET_CODE (exp)));
1134 /* FALLTHRU */
1135
1136 case IOR:
1137 case AND:
1138 XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
1139 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1140 break;
1141
1142 case FFS:
1143 XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
1144 break;
1145
1146 case COND:
1147 if (XVECLEN (exp, 0) % 2 != 0)
1148 fatal ("First operand of COND must have even length");
1149
1150 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1151 {
1152 XVECEXP (exp, 0, i) = check_attr_test (XVECEXP (exp, 0, i),
1153 attr ? attr->is_const : 0);
1154 XVECEXP (exp, 0, i + 1)
1155 = check_attr_value (XVECEXP (exp, 0, i + 1), attr);
1156 }
1157
1158 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1159 break;
1160
1161 case ATTR:
1162 {
1163 struct attr_desc *attr2 = find_attr (XSTR (exp, 0), 0);
1164 if (attr2 == NULL)
1165 fatal ("Unknown attribute `%s' in ATTR", XSTR (exp, 0));
1166 else if ((attr && attr->is_const) && ! attr2->is_const)
1167 fatal ("Non-constant attribute `%s' referenced from `%s'",
1168 XSTR (exp, 0), attr->name);
1169 else if (attr
1170 && (attr->is_numeric != attr2->is_numeric
1171 || (! attr->negative_ok && attr2->negative_ok)))
1172 fatal ("Numeric attribute mismatch calling `%s' from `%s'",
1173 XSTR (exp, 0), attr->name);
1174 }
1175 break;
1176
1177 case SYMBOL_REF:
1178 /* A constant SYMBOL_REF is valid as a constant attribute test and
1179 is expanded later by make_canonical into a COND. In a non-constant
1180 attribute test, it is left be. */
1181 return attr_rtx (SYMBOL_REF, XSTR (exp, 0));
1182
1183 default:
1184 fatal ("Invalid operation `%s' for attribute value",
1185 GET_RTX_NAME (GET_CODE (exp)));
1186 }
1187
1188 return exp;
1189 }
1190 \f
1191 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
1192 It becomes a COND with each test being (eq_attr "alternative "n") */
1193
1194 static rtx
1195 convert_set_attr_alternative (exp, num_alt, insn_index)
1196 rtx exp;
1197 int num_alt;
1198 int insn_index;
1199 {
1200 rtx condexp;
1201 int i;
1202
1203 if (XVECLEN (exp, 1) != num_alt)
1204 fatal ("Bad number of entries in SET_ATTR_ALTERNATIVE for insn %d",
1205 insn_index);
1206
1207 /* Make a COND with all tests but the last. Select the last value via the
1208 default. */
1209 condexp = rtx_alloc (COND);
1210 XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);
1211
1212 for (i = 0; i < num_alt - 1; i++)
1213 {
1214 char *p;
1215 p = attr_numeral (i);
1216
1217 XVECEXP (condexp, 0, 2 * i) = attr_eq (alternative_name, p);
1218 #if 0
1219 /* Sharing this EQ_ATTR rtl causes trouble. */
1220 XVECEXP (condexp, 0, 2 * i) = rtx_alloc (EQ_ATTR);
1221 XSTR (XVECEXP (condexp, 0, 2 * i), 0) = alternative_name;
1222 XSTR (XVECEXP (condexp, 0, 2 * i), 1) = p;
1223 #endif
1224 XVECEXP (condexp, 0, 2 * i + 1) = XVECEXP (exp, 1, i);
1225 }
1226
1227 XEXP (condexp, 1) = XVECEXP (exp, 1, i);
1228
1229 return attr_rtx (SET, attr_rtx (ATTR, XSTR (exp, 0)), condexp);
1230 }
1231 \f
1232 /* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
1233 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
1234
1235 static rtx
1236 convert_set_attr (exp, num_alt, insn_index)
1237 rtx exp;
1238 int num_alt;
1239 int insn_index;
1240 {
1241 rtx newexp;
1242 char *name_ptr;
1243 char *p;
1244 int n;
1245
1246 /* See how many alternative specified. */
1247 n = n_comma_elts (XSTR (exp, 1));
1248 if (n == 1)
1249 return attr_rtx (SET,
1250 attr_rtx (ATTR, XSTR (exp, 0)),
1251 attr_rtx (CONST_STRING, XSTR (exp, 1)));
1252
1253 newexp = rtx_alloc (SET_ATTR_ALTERNATIVE);
1254 XSTR (newexp, 0) = XSTR (exp, 0);
1255 XVEC (newexp, 1) = rtvec_alloc (n);
1256
1257 /* Process each comma-separated name. */
1258 name_ptr = XSTR (exp, 1);
1259 n = 0;
1260 while ((p = next_comma_elt (&name_ptr)) != NULL)
1261 XVECEXP (newexp, 1, n++) = attr_rtx (CONST_STRING, p);
1262
1263 return convert_set_attr_alternative (newexp, num_alt, insn_index);
1264 }
1265 \f
1266 /* Scan all definitions, checking for validity. Also, convert any SET_ATTR
1267 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
1268 expressions. */
1269
1270 static void
1271 check_defs ()
1272 {
1273 struct insn_def *id;
1274 struct attr_desc *attr;
1275 int i;
1276 rtx value;
1277
1278 for (id = defs; id; id = id->next)
1279 {
1280 if (XVEC (id->def, id->vec_idx) == NULL)
1281 continue;
1282
1283 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1284 {
1285 value = XVECEXP (id->def, id->vec_idx, i);
1286 switch (GET_CODE (value))
1287 {
1288 case SET:
1289 if (GET_CODE (XEXP (value, 0)) != ATTR)
1290 fatal ("Bad attribute set in pattern %d", id->insn_index);
1291 break;
1292
1293 case SET_ATTR_ALTERNATIVE:
1294 value = convert_set_attr_alternative (value,
1295 id->num_alternatives,
1296 id->insn_index);
1297 break;
1298
1299 case SET_ATTR:
1300 value = convert_set_attr (value, id->num_alternatives,
1301 id->insn_index);
1302 break;
1303
1304 default:
1305 fatal ("Invalid attribute code `%s' for pattern %d",
1306 GET_RTX_NAME (GET_CODE (value)), id->insn_index);
1307 }
1308
1309 if ((attr = find_attr (XSTR (XEXP (value, 0), 0), 0)) == NULL)
1310 fatal ("Unknown attribute `%s' for pattern number %d",
1311 XSTR (XEXP (value, 0), 0), id->insn_index);
1312
1313 XVECEXP (id->def, id->vec_idx, i) = value;
1314 XEXP (value, 1) = check_attr_value (XEXP (value, 1), attr);
1315 }
1316 }
1317 }
1318 \f
1319 #if 0
1320 /* Given a constant SYMBOL_REF expression, convert to a COND that
1321 explicitly tests each enumerated value. */
1322
1323 static rtx
1324 convert_const_symbol_ref (exp, attr)
1325 rtx exp;
1326 struct attr_desc *attr;
1327 {
1328 rtx condexp;
1329 struct attr_value *av;
1330 int i;
1331 int num_alt = 0;
1332
1333 for (av = attr->first_value; av; av = av->next)
1334 num_alt++;
1335
1336 /* Make a COND with all tests but the last, and in the original order.
1337 Select the last value via the default. Note that the attr values
1338 are constructed in reverse order. */
1339
1340 condexp = rtx_alloc (COND);
1341 XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);
1342 av = attr->first_value;
1343 XEXP (condexp, 1) = av->value;
1344
1345 for (i = num_alt - 2; av = av->next, i >= 0; i--)
1346 {
1347 char *p, *string;
1348 rtx value;
1349
1350 string = p = (char *) oballoc (2
1351 + strlen (attr->name)
1352 + strlen (XSTR (av->value, 0)));
1353 strcpy (p, attr->name);
1354 strcat (p, "_");
1355 strcat (p, XSTR (av->value, 0));
1356 for (; *p != '\0'; p++)
1357 *p = TOUPPER (*p);
1358
1359 value = attr_rtx (SYMBOL_REF, string);
1360 RTX_UNCHANGING_P (value) = 1;
1361
1362 XVECEXP (condexp, 0, 2 * i) = attr_rtx (EQ, exp, value);
1363
1364 XVECEXP (condexp, 0, 2 * i + 1) = av->value;
1365 }
1366
1367 return condexp;
1368 }
1369 #endif
1370 \f
1371 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1372 expressions by converting them into a COND. This removes cases from this
1373 program. Also, replace an attribute value of "*" with the default attribute
1374 value. */
1375
1376 static rtx
1377 make_canonical (attr, exp)
1378 struct attr_desc *attr;
1379 rtx exp;
1380 {
1381 int i;
1382 rtx newexp;
1383
1384 switch (GET_CODE (exp))
1385 {
1386 case CONST_INT:
1387 exp = make_numeric_value (INTVAL (exp));
1388 break;
1389
1390 case CONST_STRING:
1391 if (! strcmp (XSTR (exp, 0), "*"))
1392 {
1393 if (attr == 0 || attr->default_val == 0)
1394 fatal ("(attr_value \"*\") used in invalid context.");
1395 exp = attr->default_val->value;
1396 }
1397
1398 break;
1399
1400 case SYMBOL_REF:
1401 if (!attr->is_const || RTX_UNCHANGING_P (exp))
1402 break;
1403 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1404 This makes the COND something that won't be considered an arbitrary
1405 expression by walk_attr_value. */
1406 RTX_UNCHANGING_P (exp) = 1;
1407 #if 0
1408 /* ??? Why do we do this? With attribute values { A B C D E }, this
1409 tends to generate (!(x==A) && !(x==B) && !(x==C) && !(x==D)) rather
1410 than (x==E). */
1411 exp = convert_const_symbol_ref (exp, attr);
1412 RTX_UNCHANGING_P (exp) = 1;
1413 exp = check_attr_value (exp, attr);
1414 /* Goto COND case since this is now a COND. Note that while the
1415 new expression is rescanned, all symbol_ref notes are marked as
1416 unchanging. */
1417 goto cond;
1418 #else
1419 exp = check_attr_value (exp, attr);
1420 break;
1421 #endif
1422
1423 case IF_THEN_ELSE:
1424 newexp = rtx_alloc (COND);
1425 XVEC (newexp, 0) = rtvec_alloc (2);
1426 XVECEXP (newexp, 0, 0) = XEXP (exp, 0);
1427 XVECEXP (newexp, 0, 1) = XEXP (exp, 1);
1428
1429 XEXP (newexp, 1) = XEXP (exp, 2);
1430
1431 exp = newexp;
1432 /* Fall through to COND case since this is now a COND. */
1433
1434 case COND:
1435 {
1436 int allsame = 1;
1437 rtx defval;
1438
1439 /* First, check for degenerate COND. */
1440 if (XVECLEN (exp, 0) == 0)
1441 return make_canonical (attr, XEXP (exp, 1));
1442 defval = XEXP (exp, 1) = make_canonical (attr, XEXP (exp, 1));
1443
1444 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1445 {
1446 XVECEXP (exp, 0, i) = copy_boolean (XVECEXP (exp, 0, i));
1447 XVECEXP (exp, 0, i + 1)
1448 = make_canonical (attr, XVECEXP (exp, 0, i + 1));
1449 if (! rtx_equal_p (XVECEXP (exp, 0, i + 1), defval))
1450 allsame = 0;
1451 }
1452 if (allsame)
1453 return defval;
1454 }
1455 break;
1456
1457 default:
1458 break;
1459 }
1460
1461 return exp;
1462 }
1463
1464 static rtx
1465 copy_boolean (exp)
1466 rtx exp;
1467 {
1468 if (GET_CODE (exp) == AND || GET_CODE (exp) == IOR)
1469 return attr_rtx (GET_CODE (exp), copy_boolean (XEXP (exp, 0)),
1470 copy_boolean (XEXP (exp, 1)));
1471 return exp;
1472 }
1473 \f
1474 /* Given a value and an attribute description, return a `struct attr_value *'
1475 that represents that value. This is either an existing structure, if the
1476 value has been previously encountered, or a newly-created structure.
1477
1478 `insn_code' is the code of an insn whose attribute has the specified
1479 value (-2 if not processing an insn). We ensure that all insns for
1480 a given value have the same number of alternatives if the value checks
1481 alternatives. */
1482
1483 static struct attr_value *
1484 get_attr_value (value, attr, insn_code)
1485 rtx value;
1486 struct attr_desc *attr;
1487 int insn_code;
1488 {
1489 struct attr_value *av;
1490 int num_alt = 0;
1491
1492 value = make_canonical (attr, value);
1493 if (compares_alternatives_p (value))
1494 {
1495 if (insn_code < 0 || insn_alternatives == NULL)
1496 fatal ("(eq_attr \"alternatives\" ...) used in non-insn context");
1497 else
1498 num_alt = insn_alternatives[insn_code];
1499 }
1500
1501 for (av = attr->first_value; av; av = av->next)
1502 if (rtx_equal_p (value, av->value)
1503 && (num_alt == 0 || av->first_insn == NULL
1504 || insn_alternatives[av->first_insn->insn_code]))
1505 return av;
1506
1507 av = (struct attr_value *) oballoc (sizeof (struct attr_value));
1508 av->value = value;
1509 av->next = attr->first_value;
1510 attr->first_value = av;
1511 av->first_insn = NULL;
1512 av->num_insns = 0;
1513 av->has_asm_insn = 0;
1514
1515 return av;
1516 }
1517 \f
1518 /* After all DEFINE_DELAYs have been read in, create internal attributes
1519 to generate the required routines.
1520
1521 First, we compute the number of delay slots for each insn (as a COND of
1522 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1523 delay type is specified, we compute a similar function giving the
1524 DEFINE_DELAY ordinal for each insn.
1525
1526 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1527 tells whether a given insn can be in that delay slot.
1528
1529 Normal attribute filling and optimization expands these to contain the
1530 information needed to handle delay slots. */
1531
1532 static void
1533 expand_delays ()
1534 {
1535 struct delay_desc *delay;
1536 rtx condexp;
1537 rtx newexp;
1538 int i;
1539 char *p;
1540
1541 /* First, generate data for `num_delay_slots' function. */
1542
1543 condexp = rtx_alloc (COND);
1544 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1545 XEXP (condexp, 1) = make_numeric_value (0);
1546
1547 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1548 {
1549 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1550 XVECEXP (condexp, 0, i + 1)
1551 = make_numeric_value (XVECLEN (delay->def, 1) / 3);
1552 }
1553
1554 make_internal_attr ("*num_delay_slots", condexp, 0);
1555
1556 /* If more than one delay type, do the same for computing the delay type. */
1557 if (num_delays > 1)
1558 {
1559 condexp = rtx_alloc (COND);
1560 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1561 XEXP (condexp, 1) = make_numeric_value (0);
1562
1563 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1564 {
1565 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1566 XVECEXP (condexp, 0, i + 1) = make_numeric_value (delay->num);
1567 }
1568
1569 make_internal_attr ("*delay_type", condexp, 1);
1570 }
1571
1572 /* For each delay possibility and delay slot, compute an eligibility
1573 attribute for non-annulled insns and for each type of annulled (annul
1574 if true and annul if false). */
1575 for (delay = delays; delay; delay = delay->next)
1576 {
1577 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
1578 {
1579 condexp = XVECEXP (delay->def, 1, i);
1580 if (condexp == 0) condexp = false_rtx;
1581 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1582 make_numeric_value (1), make_numeric_value (0));
1583
1584 p = attr_printf (sizeof ("*delay__") + MAX_DIGITS*2, "*delay_%d_%d",
1585 delay->num, i / 3);
1586 make_internal_attr (p, newexp, 1);
1587
1588 if (have_annul_true)
1589 {
1590 condexp = XVECEXP (delay->def, 1, i + 1);
1591 if (condexp == 0) condexp = false_rtx;
1592 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1593 make_numeric_value (1),
1594 make_numeric_value (0));
1595 p = attr_printf (sizeof ("*annul_true__") + MAX_DIGITS*2,
1596 "*annul_true_%d_%d", delay->num, i / 3);
1597 make_internal_attr (p, newexp, 1);
1598 }
1599
1600 if (have_annul_false)
1601 {
1602 condexp = XVECEXP (delay->def, 1, i + 2);
1603 if (condexp == 0) condexp = false_rtx;
1604 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1605 make_numeric_value (1),
1606 make_numeric_value (0));
1607 p = attr_printf (sizeof ("*annul_false__") + MAX_DIGITS*2,
1608 "*annul_false_%d_%d", delay->num, i / 3);
1609 make_internal_attr (p, newexp, 1);
1610 }
1611 }
1612 }
1613 }
1614 \f
1615 /* This function is given a left and right side expression and an operator.
1616 Each side is a conditional expression, each alternative of which has a
1617 numerical value. The function returns another conditional expression
1618 which, for every possible set of condition values, returns a value that is
1619 the operator applied to the values of the two sides.
1620
1621 Since this is called early, it must also support IF_THEN_ELSE. */
1622
1623 static rtx
1624 operate_exp (op, left, right)
1625 enum operator op;
1626 rtx left, right;
1627 {
1628 int left_value, right_value;
1629 rtx newexp;
1630 int i;
1631
1632 /* If left is a string, apply operator to it and the right side. */
1633 if (GET_CODE (left) == CONST_STRING)
1634 {
1635 /* If right is also a string, just perform the operation. */
1636 if (GET_CODE (right) == CONST_STRING)
1637 {
1638 left_value = atoi (XSTR (left, 0));
1639 right_value = atoi (XSTR (right, 0));
1640 switch (op)
1641 {
1642 case PLUS_OP:
1643 i = left_value + right_value;
1644 break;
1645
1646 case MINUS_OP:
1647 i = left_value - right_value;
1648 break;
1649
1650 case POS_MINUS_OP: /* The positive part of LEFT - RIGHT. */
1651 if (left_value > right_value)
1652 i = left_value - right_value;
1653 else
1654 i = 0;
1655 break;
1656
1657 case OR_OP:
1658 case ORX_OP:
1659 i = left_value | right_value;
1660 break;
1661
1662 case EQ_OP:
1663 i = left_value == right_value;
1664 break;
1665
1666 case RANGE_OP:
1667 i = (left_value << (HOST_BITS_PER_INT / 2)) | right_value;
1668 break;
1669
1670 case MAX_OP:
1671 if (left_value > right_value)
1672 i = left_value;
1673 else
1674 i = right_value;
1675 break;
1676
1677 case MIN_OP:
1678 if (left_value < right_value)
1679 i = left_value;
1680 else
1681 i = right_value;
1682 break;
1683
1684 default:
1685 abort ();
1686 }
1687
1688 if (i == left_value)
1689 return left;
1690 if (i == right_value)
1691 return right;
1692 return make_numeric_value (i);
1693 }
1694 else if (GET_CODE (right) == IF_THEN_ELSE)
1695 {
1696 /* Apply recursively to all values within. */
1697 rtx newleft = operate_exp (op, left, XEXP (right, 1));
1698 rtx newright = operate_exp (op, left, XEXP (right, 2));
1699 if (rtx_equal_p (newleft, newright))
1700 return newleft;
1701 return attr_rtx (IF_THEN_ELSE, XEXP (right, 0), newleft, newright);
1702 }
1703 else if (GET_CODE (right) == COND)
1704 {
1705 int allsame = 1;
1706 rtx defval;
1707
1708 newexp = rtx_alloc (COND);
1709 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (right, 0));
1710 defval = XEXP (newexp, 1) = operate_exp (op, left, XEXP (right, 1));
1711
1712 for (i = 0; i < XVECLEN (right, 0); i += 2)
1713 {
1714 XVECEXP (newexp, 0, i) = XVECEXP (right, 0, i);
1715 XVECEXP (newexp, 0, i + 1)
1716 = operate_exp (op, left, XVECEXP (right, 0, i + 1));
1717 if (! rtx_equal_p (XVECEXP (newexp, 0, i + 1),
1718 defval))
1719 allsame = 0;
1720 }
1721
1722 /* If the resulting cond is trivial (all alternatives
1723 give the same value), optimize it away. */
1724 if (allsame)
1725 {
1726 if (!ggc_p)
1727 obstack_free (rtl_obstack, newexp);
1728 return operate_exp (op, left, XEXP (right, 1));
1729 }
1730
1731 /* If the result is the same as the RIGHT operand,
1732 just use that. */
1733 if (rtx_equal_p (newexp, right))
1734 {
1735 if (!ggc_p)
1736 obstack_free (rtl_obstack, newexp);
1737 return right;
1738 }
1739
1740 return newexp;
1741 }
1742 else
1743 fatal ("Badly formed attribute value");
1744 }
1745
1746 /* A hack to prevent expand_units from completely blowing up: ORX_OP does
1747 not associate through IF_THEN_ELSE. */
1748 else if (op == ORX_OP && GET_CODE (right) == IF_THEN_ELSE)
1749 {
1750 return attr_rtx (IOR, left, right);
1751 }
1752
1753 /* Otherwise, do recursion the other way. */
1754 else if (GET_CODE (left) == IF_THEN_ELSE)
1755 {
1756 rtx newleft = operate_exp (op, XEXP (left, 1), right);
1757 rtx newright = operate_exp (op, XEXP (left, 2), right);
1758 if (rtx_equal_p (newleft, newright))
1759 return newleft;
1760 return attr_rtx (IF_THEN_ELSE, XEXP (left, 0), newleft, newright);
1761 }
1762 else if (GET_CODE (left) == COND)
1763 {
1764 int allsame = 1;
1765 rtx defval;
1766
1767 newexp = rtx_alloc (COND);
1768 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (left, 0));
1769 defval = XEXP (newexp, 1) = operate_exp (op, XEXP (left, 1), right);
1770
1771 for (i = 0; i < XVECLEN (left, 0); i += 2)
1772 {
1773 XVECEXP (newexp, 0, i) = XVECEXP (left, 0, i);
1774 XVECEXP (newexp, 0, i + 1)
1775 = operate_exp (op, XVECEXP (left, 0, i + 1), right);
1776 if (! rtx_equal_p (XVECEXP (newexp, 0, i + 1),
1777 defval))
1778 allsame = 0;
1779 }
1780
1781 /* If the cond is trivial (all alternatives give the same value),
1782 optimize it away. */
1783 if (allsame)
1784 {
1785 if (!ggc_p)
1786 obstack_free (rtl_obstack, newexp);
1787 return operate_exp (op, XEXP (left, 1), right);
1788 }
1789
1790 /* If the result is the same as the LEFT operand,
1791 just use that. */
1792 if (rtx_equal_p (newexp, left))
1793 {
1794 if (!ggc_p)
1795 obstack_free (rtl_obstack, newexp);
1796 return left;
1797 }
1798
1799 return newexp;
1800 }
1801
1802 else
1803 fatal ("Badly formed attribute value.");
1804 /* NOTREACHED */
1805 return NULL;
1806 }
1807 \f
1808 /* Once all attributes and DEFINE_FUNCTION_UNITs have been read, we
1809 construct a number of attributes.
1810
1811 The first produces a function `function_units_used' which is given an
1812 insn and produces an encoding showing which function units are required
1813 for the execution of that insn. If the value is non-negative, the insn
1814 uses that unit; otherwise, the value is a one's compliment mask of units
1815 used.
1816
1817 The second produces a function `result_ready_cost' which is used to
1818 determine the time that the result of an insn will be ready and hence
1819 a worst-case schedule.
1820
1821 Both of these produce quite complex expressions which are then set as the
1822 default value of internal attributes. Normal attribute simplification
1823 should produce reasonable expressions.
1824
1825 For each unit, a `<name>_unit_ready_cost' function will take an
1826 insn and give the delay until that unit will be ready with the result
1827 and a `<name>_unit_conflict_cost' function is given an insn already
1828 executing on the unit and a candidate to execute and will give the
1829 cost from the time the executing insn started until the candidate
1830 can start (ignore limitations on the number of simultaneous insns).
1831
1832 For each unit, a `<name>_unit_blockage' function is given an insn
1833 already executing on the unit and a candidate to execute and will
1834 give the delay incurred due to function unit conflicts. The range of
1835 blockage cost values for a given executing insn is given by the
1836 `<name>_unit_blockage_range' function. These values are encoded in
1837 an int where the upper half gives the minimum value and the lower
1838 half gives the maximum value. */
1839
1840 static void
1841 expand_units ()
1842 {
1843 struct function_unit *unit, **unit_num;
1844 struct function_unit_op *op, **op_array, ***unit_ops;
1845 rtx unitsmask;
1846 rtx readycost;
1847 rtx newexp;
1848 const char *str;
1849 int i, j, u, num, nvalues;
1850
1851 /* Rebuild the condition for the unit to share the RTL expressions.
1852 Sharing is required by simplify_by_exploding. Build the issue delay
1853 expressions. Validate the expressions we were given for the conditions
1854 and conflict vector. Then make attributes for use in the conflict
1855 function. */
1856
1857 for (unit = units; unit; unit = unit->next)
1858 {
1859 unit->condexp = check_attr_test (unit->condexp, 0);
1860
1861 for (op = unit->ops; op; op = op->next)
1862 {
1863 rtx issue_delay = make_numeric_value (op->issue_delay);
1864 rtx issue_exp = issue_delay;
1865
1866 /* Build, validate, and simplify the issue delay expression. */
1867 if (op->conflict_exp != true_rtx)
1868 issue_exp = attr_rtx (IF_THEN_ELSE, op->conflict_exp,
1869 issue_exp, make_numeric_value (0));
1870 issue_exp = check_attr_value (make_canonical (NULL_ATTR,
1871 issue_exp),
1872 NULL_ATTR);
1873 issue_exp = simplify_knowing (issue_exp, unit->condexp);
1874 op->issue_exp = issue_exp;
1875
1876 /* Make an attribute for use in the conflict function if needed. */
1877 unit->needs_conflict_function = (unit->issue_delay.min
1878 != unit->issue_delay.max);
1879 if (unit->needs_conflict_function)
1880 {
1881 str = attr_printf (strlen (unit->name) + sizeof ("*_cost_") + MAX_DIGITS,
1882 "*%s_cost_%d", unit->name, op->num);
1883 make_internal_attr (str, issue_exp, 1);
1884 }
1885
1886 /* Validate the condition. */
1887 op->condexp = check_attr_test (op->condexp, 0);
1888 }
1889 }
1890
1891 /* Compute the mask of function units used. Initially, the unitsmask is
1892 zero. Set up a conditional to compute each unit's contribution. */
1893 unitsmask = make_numeric_value (0);
1894 newexp = rtx_alloc (IF_THEN_ELSE);
1895 XEXP (newexp, 2) = make_numeric_value (0);
1896
1897 /* If we have just a few units, we may be all right expanding the whole
1898 thing. But the expansion is 2**N in space on the number of opclasses,
1899 so we can't do this for very long -- Alpha and MIPS in particular have
1900 problems with this. So in that situation, we fall back on an alternate
1901 implementation method. */
1902 #define NUM_UNITOP_CUTOFF 20
1903
1904 if (num_unit_opclasses < NUM_UNITOP_CUTOFF)
1905 {
1906 /* Merge each function unit into the unit mask attributes. */
1907 for (unit = units; unit; unit = unit->next)
1908 {
1909 XEXP (newexp, 0) = unit->condexp;
1910 XEXP (newexp, 1) = make_numeric_value (1 << unit->num);
1911 unitsmask = operate_exp (OR_OP, unitsmask, newexp);
1912 }
1913 }
1914 else
1915 {
1916 /* Merge each function unit into the unit mask attributes. */
1917 for (unit = units; unit; unit = unit->next)
1918 {
1919 XEXP (newexp, 0) = unit->condexp;
1920 XEXP (newexp, 1) = make_numeric_value (1 << unit->num);
1921 unitsmask = operate_exp (ORX_OP, unitsmask, attr_copy_rtx (newexp));
1922 }
1923 }
1924
1925 /* Simplify the unit mask expression, encode it, and make an attribute
1926 for the function_units_used function. */
1927 unitsmask = simplify_by_exploding (unitsmask);
1928
1929 if (num_unit_opclasses < NUM_UNITOP_CUTOFF)
1930 unitsmask = encode_units_mask (unitsmask);
1931 else
1932 {
1933 /* We can no longer encode unitsmask at compile time, so emit code to
1934 calculate it at runtime. Rather, put a marker for where we'd do
1935 the code, and actually output it in write_attr_get(). */
1936 unitsmask = attr_rtx (FFS, unitsmask);
1937 }
1938
1939 make_internal_attr ("*function_units_used", unitsmask, 10);
1940
1941 /* Create an array of ops for each unit. Add an extra unit for the
1942 result_ready_cost function that has the ops of all other units. */
1943 unit_ops = (struct function_unit_op ***)
1944 alloca ((num_units + 1) * sizeof (struct function_unit_op **));
1945 unit_num = (struct function_unit **)
1946 alloca ((num_units + 1) * sizeof (struct function_unit *));
1947
1948 unit_num[num_units] = unit = (struct function_unit *)
1949 alloca (sizeof (struct function_unit));
1950 unit->num = num_units;
1951 unit->num_opclasses = 0;
1952
1953 for (unit = units; unit; unit = unit->next)
1954 {
1955 unit_num[num_units]->num_opclasses += unit->num_opclasses;
1956 unit_num[unit->num] = unit;
1957 unit_ops[unit->num] = op_array = (struct function_unit_op **)
1958 alloca (unit->num_opclasses * sizeof (struct function_unit_op *));
1959
1960 for (op = unit->ops; op; op = op->next)
1961 op_array[op->num] = op;
1962 }
1963
1964 /* Compose the array of ops for the extra unit. */
1965 unit_ops[num_units] = op_array = (struct function_unit_op **)
1966 alloca (unit_num[num_units]->num_opclasses
1967 * sizeof (struct function_unit_op *));
1968
1969 for (unit = units, i = 0; unit; i += unit->num_opclasses, unit = unit->next)
1970 bcopy ((char *) unit_ops[unit->num], (char *) &op_array[i],
1971 unit->num_opclasses * sizeof (struct function_unit_op *));
1972
1973 /* Compute the ready cost function for each unit by computing the
1974 condition for each non-default value. */
1975 for (u = 0; u <= num_units; u++)
1976 {
1977 rtx orexp;
1978 int value;
1979
1980 unit = unit_num[u];
1981 op_array = unit_ops[unit->num];
1982 num = unit->num_opclasses;
1983
1984 /* Sort the array of ops into increasing ready cost order. */
1985 for (i = 0; i < num; i++)
1986 for (j = num - 1; j > i; j--)
1987 if (op_array[j-1]->ready < op_array[j]->ready)
1988 {
1989 op = op_array[j];
1990 op_array[j] = op_array[j-1];
1991 op_array[j-1] = op;
1992 }
1993
1994 /* Determine how many distinct non-default ready cost values there
1995 are. We use a default ready cost value of 1. */
1996 nvalues = 0; value = 1;
1997 for (i = num - 1; i >= 0; i--)
1998 if (op_array[i]->ready > value)
1999 {
2000 value = op_array[i]->ready;
2001 nvalues++;
2002 }
2003
2004 if (nvalues == 0)
2005 readycost = make_numeric_value (1);
2006 else
2007 {
2008 /* Construct the ready cost expression as a COND of each value from
2009 the largest to the smallest. */
2010 readycost = rtx_alloc (COND);
2011 XVEC (readycost, 0) = rtvec_alloc (nvalues * 2);
2012 XEXP (readycost, 1) = make_numeric_value (1);
2013
2014 nvalues = 0; orexp = false_rtx; value = op_array[0]->ready;
2015 for (i = 0; i < num; i++)
2016 {
2017 op = op_array[i];
2018 if (op->ready <= 1)
2019 break;
2020 else if (op->ready == value)
2021 orexp = insert_right_side (IOR, orexp, op->condexp, -2, -2);
2022 else
2023 {
2024 XVECEXP (readycost, 0, nvalues * 2) = orexp;
2025 XVECEXP (readycost, 0, nvalues * 2 + 1)
2026 = make_numeric_value (value);
2027 nvalues++;
2028 value = op->ready;
2029 orexp = op->condexp;
2030 }
2031 }
2032 XVECEXP (readycost, 0, nvalues * 2) = orexp;
2033 XVECEXP (readycost, 0, nvalues * 2 + 1) = make_numeric_value (value);
2034 }
2035
2036 if (u < num_units)
2037 {
2038 rtx max_blockage = 0, min_blockage = 0;
2039
2040 /* Simplify the readycost expression by only considering insns
2041 that use the unit. */
2042 readycost = simplify_knowing (readycost, unit->condexp);
2043
2044 /* Determine the blockage cost the executing insn (E) given
2045 the candidate insn (C). This is the maximum of the issue
2046 delay, the pipeline delay, and the simultaneity constraint.
2047 Each function_unit_op represents the characteristics of the
2048 candidate insn, so in the expressions below, C is a known
2049 term and E is an unknown term.
2050
2051 We compute the blockage cost for each E for every possible C.
2052 Thus OP represents E, and READYCOST is a list of values for
2053 every possible C.
2054
2055 The issue delay function for C is op->issue_exp and is used to
2056 write the `<name>_unit_conflict_cost' function. Symbolicly
2057 this is "ISSUE-DELAY (E,C)".
2058
2059 The pipeline delay results form the FIFO constraint on the
2060 function unit and is "READY-COST (E) + 1 - READY-COST (C)".
2061
2062 The simultaneity constraint is based on how long it takes to
2063 fill the unit given the minimum issue delay. FILL-TIME is the
2064 constant "MIN (ISSUE-DELAY (*,*)) * (SIMULTANEITY - 1)", and
2065 the simultaneity constraint is "READY-COST (E) - FILL-TIME"
2066 if SIMULTANEITY is non-zero and zero otherwise.
2067
2068 Thus, BLOCKAGE (E,C) when SIMULTANEITY is zero is
2069
2070 MAX (ISSUE-DELAY (E,C),
2071 READY-COST (E) - (READY-COST (C) - 1))
2072
2073 and otherwise
2074
2075 MAX (ISSUE-DELAY (E,C),
2076 READY-COST (E) - (READY-COST (C) - 1),
2077 READY-COST (E) - FILL-TIME)
2078
2079 The `<name>_unit_blockage' function is computed by determining
2080 this value for each candidate insn. As these values are
2081 computed, we also compute the upper and lower bounds for
2082 BLOCKAGE (E,*). These are combined to form the function
2083 `<name>_unit_blockage_range'. Finally, the maximum blockage
2084 cost, MAX (BLOCKAGE (*,*)), is computed. */
2085
2086 for (op = unit->ops; op; op = op->next)
2087 {
2088 rtx blockage = op->issue_exp;
2089 blockage = simplify_knowing (blockage, unit->condexp);
2090
2091 /* Add this op's contribution to MAX (BLOCKAGE (E,*)) and
2092 MIN (BLOCKAGE (E,*)). */
2093 if (max_blockage == 0)
2094 max_blockage = min_blockage = blockage;
2095 else
2096 {
2097 max_blockage
2098 = simplify_knowing (operate_exp (MAX_OP, max_blockage,
2099 blockage),
2100 unit->condexp);
2101 min_blockage
2102 = simplify_knowing (operate_exp (MIN_OP, min_blockage,
2103 blockage),
2104 unit->condexp);
2105 }
2106
2107 /* Make an attribute for use in the blockage function. */
2108 str = attr_printf (strlen (unit->name) + sizeof ("*_block_") + MAX_DIGITS,
2109 "*%s_block_%d", unit->name, op->num);
2110 make_internal_attr (str, blockage, 1);
2111 }
2112
2113 /* Record MAX (BLOCKAGE (*,*)). */
2114 {
2115 int unknown;
2116 unit->max_blockage = max_attr_value (max_blockage, &unknown);
2117 }
2118
2119 /* See if the upper and lower bounds of BLOCKAGE (E,*) are the
2120 same. If so, the blockage function carries no additional
2121 information and is not written. */
2122 newexp = operate_exp (EQ_OP, max_blockage, min_blockage);
2123 newexp = simplify_knowing (newexp, unit->condexp);
2124 unit->needs_blockage_function
2125 = (GET_CODE (newexp) != CONST_STRING
2126 || atoi (XSTR (newexp, 0)) != 1);
2127
2128 /* If the all values of BLOCKAGE (E,C) have the same value,
2129 neither blockage function is written. */
2130 unit->needs_range_function
2131 = (unit->needs_blockage_function
2132 || GET_CODE (max_blockage) != CONST_STRING);
2133
2134 if (unit->needs_range_function)
2135 {
2136 /* Compute the blockage range function and make an attribute
2137 for writing its value. */
2138 newexp = operate_exp (RANGE_OP, min_blockage, max_blockage);
2139 newexp = simplify_knowing (newexp, unit->condexp);
2140
2141 str = attr_printf (strlen (unit->name) + sizeof ("*_unit_blockage_range"),
2142 "*%s_unit_blockage_range", unit->name);
2143 make_internal_attr (str, newexp, 20);
2144 }
2145
2146 str = attr_printf (strlen (unit->name) + sizeof ("*_unit_ready_cost"),
2147 "*%s_unit_ready_cost", unit->name);
2148 }
2149 else
2150 str = "*result_ready_cost";
2151
2152 /* Make an attribute for the ready_cost function. Simplifying
2153 further with simplify_by_exploding doesn't win. */
2154 make_internal_attr (str, readycost, 0);
2155 }
2156
2157 /* For each unit that requires a conflict cost function, make an attribute
2158 that maps insns to the operation number. */
2159 for (unit = units; unit; unit = unit->next)
2160 {
2161 rtx caseexp;
2162
2163 if (! unit->needs_conflict_function
2164 && ! unit->needs_blockage_function)
2165 continue;
2166
2167 caseexp = rtx_alloc (COND);
2168 XVEC (caseexp, 0) = rtvec_alloc ((unit->num_opclasses - 1) * 2);
2169
2170 for (op = unit->ops; op; op = op->next)
2171 {
2172 /* Make our adjustment to the COND being computed. If we are the
2173 last operation class, place our values into the default of the
2174 COND. */
2175 if (op->num == unit->num_opclasses - 1)
2176 {
2177 XEXP (caseexp, 1) = make_numeric_value (op->num);
2178 }
2179 else
2180 {
2181 XVECEXP (caseexp, 0, op->num * 2) = op->condexp;
2182 XVECEXP (caseexp, 0, op->num * 2 + 1)
2183 = make_numeric_value (op->num);
2184 }
2185 }
2186
2187 /* Simplifying caseexp with simplify_by_exploding doesn't win. */
2188 str = attr_printf (strlen (unit->name) + sizeof ("*_cases"),
2189 "*%s_cases", unit->name);
2190 make_internal_attr (str, caseexp, 1);
2191 }
2192 }
2193
2194 /* Simplify EXP given KNOWN_TRUE. */
2195
2196 static rtx
2197 simplify_knowing (exp, known_true)
2198 rtx exp, known_true;
2199 {
2200 if (GET_CODE (exp) != CONST_STRING)
2201 {
2202 int unknown = 0, max;
2203 max = max_attr_value (exp, &unknown);
2204 if (! unknown)
2205 {
2206 exp = attr_rtx (IF_THEN_ELSE, known_true, exp,
2207 make_numeric_value (max));
2208 exp = simplify_by_exploding (exp);
2209 }
2210 }
2211 return exp;
2212 }
2213
2214 /* Translate the CONST_STRING expressions in X to change the encoding of
2215 value. On input, the value is a bitmask with a one bit for each unit
2216 used; on output, the value is the unit number (zero based) if one
2217 and only one unit is used or the one's compliment of the bitmask. */
2218
2219 static rtx
2220 encode_units_mask (x)
2221 rtx x;
2222 {
2223 register int i;
2224 register int j;
2225 register enum rtx_code code;
2226 register const char *fmt;
2227
2228 code = GET_CODE (x);
2229
2230 switch (code)
2231 {
2232 case CONST_STRING:
2233 i = atoi (XSTR (x, 0));
2234 if (i < 0)
2235 abort (); /* The sign bit encodes a one's compliment mask. */
2236 else if (i != 0 && i == (i & -i))
2237 /* Only one bit is set, so yield that unit number. */
2238 for (j = 0; (i >>= 1) != 0; j++)
2239 ;
2240 else
2241 j = ~i;
2242 return attr_rtx (CONST_STRING, attr_printf (MAX_DIGITS, "%d", j));
2243
2244 case REG:
2245 case QUEUED:
2246 case CONST_INT:
2247 case CONST_DOUBLE:
2248 case SYMBOL_REF:
2249 case CODE_LABEL:
2250 case PC:
2251 case CC0:
2252 case EQ_ATTR:
2253 return x;
2254
2255 default:
2256 break;
2257 }
2258
2259 /* Compare the elements. If any pair of corresponding elements
2260 fail to match, return 0 for the whole things. */
2261
2262 fmt = GET_RTX_FORMAT (code);
2263 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
2264 {
2265 switch (fmt[i])
2266 {
2267 case 'V':
2268 case 'E':
2269 for (j = 0; j < XVECLEN (x, i); j++)
2270 XVECEXP (x, i, j) = encode_units_mask (XVECEXP (x, i, j));
2271 break;
2272
2273 case 'e':
2274 XEXP (x, i) = encode_units_mask (XEXP (x, i));
2275 break;
2276 }
2277 }
2278 return x;
2279 }
2280 \f
2281 /* Once all attributes and insns have been read and checked, we construct for
2282 each attribute value a list of all the insns that have that value for
2283 the attribute. */
2284
2285 static void
2286 fill_attr (attr)
2287 struct attr_desc *attr;
2288 {
2289 struct attr_value *av;
2290 struct insn_ent *ie;
2291 struct insn_def *id;
2292 int i;
2293 rtx value;
2294
2295 /* Don't fill constant attributes. The value is independent of
2296 any particular insn. */
2297 if (attr->is_const)
2298 return;
2299
2300 for (id = defs; id; id = id->next)
2301 {
2302 /* If no value is specified for this insn for this attribute, use the
2303 default. */
2304 value = NULL;
2305 if (XVEC (id->def, id->vec_idx))
2306 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
2307 if (! strcmp (XSTR (XEXP (XVECEXP (id->def, id->vec_idx, i), 0), 0),
2308 attr->name))
2309 value = XEXP (XVECEXP (id->def, id->vec_idx, i), 1);
2310
2311 if (value == NULL)
2312 av = attr->default_val;
2313 else
2314 av = get_attr_value (value, attr, id->insn_code);
2315
2316 ie = (struct insn_ent *) oballoc (sizeof (struct insn_ent));
2317 ie->insn_code = id->insn_code;
2318 ie->insn_index = id->insn_code;
2319 insert_insn_ent (av, ie);
2320 }
2321 }
2322 \f
2323 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
2324 test that checks relative positions of insns (uses MATCH_DUP or PC).
2325 If so, replace it with what is obtained by passing the expression to
2326 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
2327 recursively on each value (including the default value). Otherwise,
2328 return the value returned by NO_ADDRESS_FN applied to EXP. */
2329
2330 static rtx
2331 substitute_address (exp, no_address_fn, address_fn)
2332 rtx exp;
2333 rtx (*no_address_fn) PROTO ((rtx));
2334 rtx (*address_fn) PROTO ((rtx));
2335 {
2336 int i;
2337 rtx newexp;
2338
2339 if (GET_CODE (exp) == COND)
2340 {
2341 /* See if any tests use addresses. */
2342 address_used = 0;
2343 for (i = 0; i < XVECLEN (exp, 0); i += 2)
2344 walk_attr_value (XVECEXP (exp, 0, i));
2345
2346 if (address_used)
2347 return (*address_fn) (exp);
2348
2349 /* Make a new copy of this COND, replacing each element. */
2350 newexp = rtx_alloc (COND);
2351 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
2352 for (i = 0; i < XVECLEN (exp, 0); i += 2)
2353 {
2354 XVECEXP (newexp, 0, i) = XVECEXP (exp, 0, i);
2355 XVECEXP (newexp, 0, i + 1)
2356 = substitute_address (XVECEXP (exp, 0, i + 1),
2357 no_address_fn, address_fn);
2358 }
2359
2360 XEXP (newexp, 1) = substitute_address (XEXP (exp, 1),
2361 no_address_fn, address_fn);
2362
2363 return newexp;
2364 }
2365
2366 else if (GET_CODE (exp) == IF_THEN_ELSE)
2367 {
2368 address_used = 0;
2369 walk_attr_value (XEXP (exp, 0));
2370 if (address_used)
2371 return (*address_fn) (exp);
2372
2373 return attr_rtx (IF_THEN_ELSE,
2374 substitute_address (XEXP (exp, 0),
2375 no_address_fn, address_fn),
2376 substitute_address (XEXP (exp, 1),
2377 no_address_fn, address_fn),
2378 substitute_address (XEXP (exp, 2),
2379 no_address_fn, address_fn));
2380 }
2381
2382 return (*no_address_fn) (exp);
2383 }
2384 \f
2385 /* Make new attributes from the `length' attribute. The following are made,
2386 each corresponding to a function called from `shorten_branches' or
2387 `get_attr_length':
2388
2389 *insn_default_length This is the length of the insn to be returned
2390 by `get_attr_length' before `shorten_branches'
2391 has been called. In each case where the length
2392 depends on relative addresses, the largest
2393 possible is used. This routine is also used
2394 to compute the initial size of the insn.
2395
2396 *insn_variable_length_p This returns 1 if the insn's length depends
2397 on relative addresses, zero otherwise.
2398
2399 *insn_current_length This is only called when it is known that the
2400 insn has a variable length and returns the
2401 current length, based on relative addresses.
2402 */
2403
2404 static void
2405 make_length_attrs ()
2406 {
2407 static const char *new_names[] = {"*insn_default_length",
2408 "*insn_variable_length_p",
2409 "*insn_current_length"};
2410 static rtx (*no_address_fn[]) PROTO((rtx)) = {identity_fn, zero_fn, zero_fn};
2411 static rtx (*address_fn[]) PROTO((rtx)) = {max_fn, one_fn, identity_fn};
2412 size_t i;
2413 struct attr_desc *length_attr, *new_attr;
2414 struct attr_value *av, *new_av;
2415 struct insn_ent *ie, *new_ie;
2416
2417 /* See if length attribute is defined. If so, it must be numeric. Make
2418 it special so we don't output anything for it. */
2419 length_attr = find_attr ("length", 0);
2420 if (length_attr == 0)
2421 return;
2422
2423 if (! length_attr->is_numeric)
2424 fatal ("length attribute must be numeric.");
2425
2426 length_attr->is_const = 0;
2427 length_attr->is_special = 1;
2428
2429 /* Make each new attribute, in turn. */
2430 for (i = 0; i < sizeof new_names / sizeof new_names[0]; i++)
2431 {
2432 make_internal_attr (new_names[i],
2433 substitute_address (length_attr->default_val->value,
2434 no_address_fn[i], address_fn[i]),
2435 0);
2436 new_attr = find_attr (new_names[i], 0);
2437 for (av = length_attr->first_value; av; av = av->next)
2438 for (ie = av->first_insn; ie; ie = ie->next)
2439 {
2440 new_av = get_attr_value (substitute_address (av->value,
2441 no_address_fn[i],
2442 address_fn[i]),
2443 new_attr, ie->insn_code);
2444 new_ie = (struct insn_ent *) oballoc (sizeof (struct insn_ent));
2445 new_ie->insn_code = ie->insn_code;
2446 new_ie->insn_index = ie->insn_index;
2447 insert_insn_ent (new_av, new_ie);
2448 }
2449 }
2450 }
2451
2452 /* Utility functions called from above routine. */
2453
2454 static rtx
2455 identity_fn (exp)
2456 rtx exp;
2457 {
2458 return exp;
2459 }
2460
2461 static rtx
2462 zero_fn (exp)
2463 rtx exp ATTRIBUTE_UNUSED;
2464 {
2465 return make_numeric_value (0);
2466 }
2467
2468 static rtx
2469 one_fn (exp)
2470 rtx exp ATTRIBUTE_UNUSED;
2471 {
2472 return make_numeric_value (1);
2473 }
2474
2475 static rtx
2476 max_fn (exp)
2477 rtx exp;
2478 {
2479 int unknown;
2480 return make_numeric_value (max_attr_value (exp, &unknown));
2481 }
2482
2483 static void
2484 write_length_unit_log ()
2485 {
2486 struct attr_desc *length_attr = find_attr ("length", 0);
2487 struct attr_value *av;
2488 struct insn_ent *ie;
2489 unsigned int length_unit_log, length_or;
2490 int unknown = 0;
2491
2492 if (length_attr == 0)
2493 return;
2494 length_or = or_attr_value (length_attr->default_val->value, &unknown);
2495 for (av = length_attr->first_value; av; av = av->next)
2496 for (ie = av->first_insn; ie; ie = ie->next)
2497 length_or |= or_attr_value (av->value, &unknown);
2498
2499 if (unknown)
2500 length_unit_log = 0;
2501 else
2502 {
2503 length_or = ~length_or;
2504 for (length_unit_log = 0; length_or & 1; length_or >>= 1)
2505 length_unit_log++;
2506 }
2507 printf ("int length_unit_log = %u;\n", length_unit_log);
2508 }
2509 \f
2510 /* Take a COND expression and see if any of the conditions in it can be
2511 simplified. If any are known true or known false for the particular insn
2512 code, the COND can be further simplified.
2513
2514 Also call ourselves on any COND operations that are values of this COND.
2515
2516 We do not modify EXP; rather, we make and return a new rtx. */
2517
2518 static rtx
2519 simplify_cond (exp, insn_code, insn_index)
2520 rtx exp;
2521 int insn_code, insn_index;
2522 {
2523 int i, j;
2524 /* We store the desired contents here,
2525 then build a new expression if they don't match EXP. */
2526 rtx defval = XEXP (exp, 1);
2527 rtx new_defval = XEXP (exp, 1);
2528 int len = XVECLEN (exp, 0);
2529 rtunion *tests = (rtunion *) alloca (len * sizeof (rtunion));
2530 int allsame = 1;
2531 char *first_spacer;
2532
2533 /* This lets us free all storage allocated below, if appropriate. */
2534 first_spacer = (char *) obstack_finish (rtl_obstack);
2535
2536 bcopy ((char *) XVEC (exp, 0)->elem, (char *) tests, len * sizeof (rtunion));
2537
2538 /* See if default value needs simplification. */
2539 if (GET_CODE (defval) == COND)
2540 new_defval = simplify_cond (defval, insn_code, insn_index);
2541
2542 /* Simplify the subexpressions, and see what tests we can get rid of. */
2543
2544 for (i = 0; i < len; i += 2)
2545 {
2546 rtx newtest, newval;
2547
2548 /* Simplify this test. */
2549 newtest = SIMPLIFY_TEST_EXP (tests[i].rtx, insn_code, insn_index);
2550 tests[i].rtx = newtest;
2551
2552 newval = tests[i + 1].rtx;
2553 /* See if this value may need simplification. */
2554 if (GET_CODE (newval) == COND)
2555 newval = simplify_cond (newval, insn_code, insn_index);
2556
2557 /* Look for ways to delete or combine this test. */
2558 if (newtest == true_rtx)
2559 {
2560 /* If test is true, make this value the default
2561 and discard this + any following tests. */
2562 len = i;
2563 defval = tests[i + 1].rtx;
2564 new_defval = newval;
2565 }
2566
2567 else if (newtest == false_rtx)
2568 {
2569 /* If test is false, discard it and its value. */
2570 for (j = i; j < len - 2; j++)
2571 tests[j].rtx = tests[j + 2].rtx;
2572 len -= 2;
2573 }
2574
2575 else if (i > 0 && attr_equal_p (newval, tests[i - 1].rtx))
2576 {
2577 /* If this value and the value for the prev test are the same,
2578 merge the tests. */
2579
2580 tests[i - 2].rtx
2581 = insert_right_side (IOR, tests[i - 2].rtx, newtest,
2582 insn_code, insn_index);
2583
2584 /* Delete this test/value. */
2585 for (j = i; j < len - 2; j++)
2586 tests[j].rtx = tests[j + 2].rtx;
2587 len -= 2;
2588 }
2589
2590 else
2591 tests[i + 1].rtx = newval;
2592 }
2593
2594 /* If the last test in a COND has the same value
2595 as the default value, that test isn't needed. */
2596
2597 while (len > 0 && attr_equal_p (tests[len - 1].rtx, new_defval))
2598 len -= 2;
2599
2600 /* See if we changed anything. */
2601 if (len != XVECLEN (exp, 0) || new_defval != XEXP (exp, 1))
2602 allsame = 0;
2603 else
2604 for (i = 0; i < len; i++)
2605 if (! attr_equal_p (tests[i].rtx, XVECEXP (exp, 0, i)))
2606 {
2607 allsame = 0;
2608 break;
2609 }
2610
2611 if (len == 0)
2612 {
2613 if (!ggc_p)
2614 obstack_free (rtl_obstack, first_spacer);
2615 if (GET_CODE (defval) == COND)
2616 return simplify_cond (defval, insn_code, insn_index);
2617 return defval;
2618 }
2619 else if (allsame)
2620 {
2621 if (!ggc_p)
2622 obstack_free (rtl_obstack, first_spacer);
2623 return exp;
2624 }
2625 else
2626 {
2627 rtx newexp = rtx_alloc (COND);
2628
2629 XVEC (newexp, 0) = rtvec_alloc (len);
2630 bcopy ((char *) tests, (char *) XVEC (newexp, 0)->elem,
2631 len * sizeof (rtunion));
2632 XEXP (newexp, 1) = new_defval;
2633 return newexp;
2634 }
2635 }
2636 \f
2637 /* Remove an insn entry from an attribute value. */
2638
2639 static void
2640 remove_insn_ent (av, ie)
2641 struct attr_value *av;
2642 struct insn_ent *ie;
2643 {
2644 struct insn_ent *previe;
2645
2646 if (av->first_insn == ie)
2647 av->first_insn = ie->next;
2648 else
2649 {
2650 for (previe = av->first_insn; previe->next != ie; previe = previe->next)
2651 ;
2652 previe->next = ie->next;
2653 }
2654
2655 av->num_insns--;
2656 if (ie->insn_code == -1)
2657 av->has_asm_insn = 0;
2658
2659 num_insn_ents--;
2660 }
2661
2662 /* Insert an insn entry in an attribute value list. */
2663
2664 static void
2665 insert_insn_ent (av, ie)
2666 struct attr_value *av;
2667 struct insn_ent *ie;
2668 {
2669 ie->next = av->first_insn;
2670 av->first_insn = ie;
2671 av->num_insns++;
2672 if (ie->insn_code == -1)
2673 av->has_asm_insn = 1;
2674
2675 num_insn_ents++;
2676 }
2677 \f
2678 /* This is a utility routine to take an expression that is a tree of either
2679 AND or IOR expressions and insert a new term. The new term will be
2680 inserted at the right side of the first node whose code does not match
2681 the root. A new node will be created with the root's code. Its left
2682 side will be the old right side and its right side will be the new
2683 term.
2684
2685 If the `term' is itself a tree, all its leaves will be inserted. */
2686
2687 static rtx
2688 insert_right_side (code, exp, term, insn_code, insn_index)
2689 enum rtx_code code;
2690 rtx exp;
2691 rtx term;
2692 int insn_code, insn_index;
2693 {
2694 rtx newexp;
2695
2696 /* Avoid consing in some special cases. */
2697 if (code == AND && term == true_rtx)
2698 return exp;
2699 if (code == AND && term == false_rtx)
2700 return false_rtx;
2701 if (code == AND && exp == true_rtx)
2702 return term;
2703 if (code == AND && exp == false_rtx)
2704 return false_rtx;
2705 if (code == IOR && term == true_rtx)
2706 return true_rtx;
2707 if (code == IOR && term == false_rtx)
2708 return exp;
2709 if (code == IOR && exp == true_rtx)
2710 return true_rtx;
2711 if (code == IOR && exp == false_rtx)
2712 return term;
2713 if (attr_equal_p (exp, term))
2714 return exp;
2715
2716 if (GET_CODE (term) == code)
2717 {
2718 exp = insert_right_side (code, exp, XEXP (term, 0),
2719 insn_code, insn_index);
2720 exp = insert_right_side (code, exp, XEXP (term, 1),
2721 insn_code, insn_index);
2722
2723 return exp;
2724 }
2725
2726 if (GET_CODE (exp) == code)
2727 {
2728 rtx new = insert_right_side (code, XEXP (exp, 1),
2729 term, insn_code, insn_index);
2730 if (new != XEXP (exp, 1))
2731 /* Make a copy of this expression and call recursively. */
2732 newexp = attr_rtx (code, XEXP (exp, 0), new);
2733 else
2734 newexp = exp;
2735 }
2736 else
2737 {
2738 /* Insert the new term. */
2739 newexp = attr_rtx (code, exp, term);
2740 }
2741
2742 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2743 }
2744 \f
2745 /* If we have an expression which AND's a bunch of
2746 (not (eq_attrq "alternative" "n"))
2747 terms, we may have covered all or all but one of the possible alternatives.
2748 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
2749
2750 This routine is passed an expression and either AND or IOR. It returns a
2751 bitmask indicating which alternatives are mentioned within EXP. */
2752
2753 static int
2754 compute_alternative_mask (exp, code)
2755 rtx exp;
2756 enum rtx_code code;
2757 {
2758 char *string;
2759 if (GET_CODE (exp) == code)
2760 return compute_alternative_mask (XEXP (exp, 0), code)
2761 | compute_alternative_mask (XEXP (exp, 1), code);
2762
2763 else if (code == AND && GET_CODE (exp) == NOT
2764 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
2765 && XSTR (XEXP (exp, 0), 0) == alternative_name)
2766 string = XSTR (XEXP (exp, 0), 1);
2767
2768 else if (code == IOR && GET_CODE (exp) == EQ_ATTR
2769 && XSTR (exp, 0) == alternative_name)
2770 string = XSTR (exp, 1);
2771
2772 else
2773 return 0;
2774
2775 if (string[1] == 0)
2776 return 1 << (string[0] - '0');
2777 return 1 << atoi (string);
2778 }
2779
2780 /* Given I, a single-bit mask, return RTX to compare the `alternative'
2781 attribute with the value represented by that bit. */
2782
2783 static rtx
2784 make_alternative_compare (mask)
2785 int mask;
2786 {
2787 rtx newexp;
2788 int i;
2789
2790 /* Find the bit. */
2791 for (i = 0; (mask & (1 << i)) == 0; i++)
2792 ;
2793
2794 newexp = attr_rtx (EQ_ATTR, alternative_name, attr_numeral (i));
2795 RTX_UNCHANGING_P (newexp) = 1;
2796
2797 return newexp;
2798 }
2799 \f
2800 /* If we are processing an (eq_attr "attr" "value") test, we find the value
2801 of "attr" for this insn code. From that value, we can compute a test
2802 showing when the EQ_ATTR will be true. This routine performs that
2803 computation. If a test condition involves an address, we leave the EQ_ATTR
2804 intact because addresses are only valid for the `length' attribute.
2805
2806 EXP is the EQ_ATTR expression and VALUE is the value of that attribute
2807 for the insn corresponding to INSN_CODE and INSN_INDEX. */
2808
2809 static rtx
2810 evaluate_eq_attr (exp, value, insn_code, insn_index)
2811 rtx exp;
2812 rtx value;
2813 int insn_code, insn_index;
2814 {
2815 rtx orexp, andexp;
2816 rtx right;
2817 rtx newexp;
2818 int i;
2819
2820 if (GET_CODE (value) == CONST_STRING)
2821 {
2822 if (! strcmp (XSTR (value, 0), XSTR (exp, 1)))
2823 newexp = true_rtx;
2824 else
2825 newexp = false_rtx;
2826 }
2827 else if (GET_CODE (value) == SYMBOL_REF)
2828 {
2829 char *p, *string;
2830
2831 if (GET_CODE (exp) != EQ_ATTR)
2832 abort();
2833
2834 string = (char *) alloca (2 + strlen (XSTR (exp, 0))
2835 + strlen (XSTR (exp, 1)));
2836 strcpy (string, XSTR (exp, 0));
2837 strcat (string, "_");
2838 strcat (string, XSTR (exp, 1));
2839 for (p = string; *p ; p++)
2840 *p = TOUPPER (*p);
2841
2842 newexp = attr_rtx (EQ, value,
2843 attr_rtx (SYMBOL_REF,
2844 attr_string(string, strlen(string))));
2845 }
2846 else if (GET_CODE (value) == COND)
2847 {
2848 /* We construct an IOR of all the cases for which the requested attribute
2849 value is present. Since we start with FALSE, if it is not present,
2850 FALSE will be returned.
2851
2852 Each case is the AND of the NOT's of the previous conditions with the
2853 current condition; in the default case the current condition is TRUE.
2854
2855 For each possible COND value, call ourselves recursively.
2856
2857 The extra TRUE and FALSE expressions will be eliminated by another
2858 call to the simplification routine. */
2859
2860 orexp = false_rtx;
2861 andexp = true_rtx;
2862
2863 if (current_alternative_string)
2864 clear_struct_flag (value);
2865
2866 for (i = 0; i < XVECLEN (value, 0); i += 2)
2867 {
2868 rtx this = SIMPLIFY_TEST_EXP (XVECEXP (value, 0, i),
2869 insn_code, insn_index);
2870
2871 SIMPLIFY_ALTERNATIVE (this);
2872
2873 right = insert_right_side (AND, andexp, this,
2874 insn_code, insn_index);
2875 right = insert_right_side (AND, right,
2876 evaluate_eq_attr (exp,
2877 XVECEXP (value, 0,
2878 i + 1),
2879 insn_code, insn_index),
2880 insn_code, insn_index);
2881 orexp = insert_right_side (IOR, orexp, right,
2882 insn_code, insn_index);
2883
2884 /* Add this condition into the AND expression. */
2885 newexp = attr_rtx (NOT, this);
2886 andexp = insert_right_side (AND, andexp, newexp,
2887 insn_code, insn_index);
2888 }
2889
2890 /* Handle the default case. */
2891 right = insert_right_side (AND, andexp,
2892 evaluate_eq_attr (exp, XEXP (value, 1),
2893 insn_code, insn_index),
2894 insn_code, insn_index);
2895 newexp = insert_right_side (IOR, orexp, right, insn_code, insn_index);
2896 }
2897 else
2898 abort ();
2899
2900 /* If uses an address, must return original expression. But set the
2901 RTX_UNCHANGING_P bit so we don't try to simplify it again. */
2902
2903 address_used = 0;
2904 walk_attr_value (newexp);
2905
2906 if (address_used)
2907 {
2908 /* This had `&& current_alternative_string', which seems to be wrong. */
2909 if (! RTX_UNCHANGING_P (exp))
2910 return copy_rtx_unchanging (exp);
2911 return exp;
2912 }
2913 else
2914 return newexp;
2915 }
2916 \f
2917 /* This routine is called when an AND of a term with a tree of AND's is
2918 encountered. If the term or its complement is present in the tree, it
2919 can be replaced with TRUE or FALSE, respectively.
2920
2921 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2922 be true and hence are complementary.
2923
2924 There is one special case: If we see
2925 (and (not (eq_attr "att" "v1"))
2926 (eq_attr "att" "v2"))
2927 this can be replaced by (eq_attr "att" "v2"). To do this we need to
2928 replace the term, not anything in the AND tree. So we pass a pointer to
2929 the term. */
2930
2931 static rtx
2932 simplify_and_tree (exp, pterm, insn_code, insn_index)
2933 rtx exp;
2934 rtx *pterm;
2935 int insn_code, insn_index;
2936 {
2937 rtx left, right;
2938 rtx newexp;
2939 rtx temp;
2940 int left_eliminates_term, right_eliminates_term;
2941
2942 if (GET_CODE (exp) == AND)
2943 {
2944 left = simplify_and_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
2945 right = simplify_and_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2946 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2947 {
2948 newexp = attr_rtx (GET_CODE (exp), left, right);
2949
2950 exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2951 }
2952 }
2953
2954 else if (GET_CODE (exp) == IOR)
2955 {
2956 /* For the IOR case, we do the same as above, except that we can
2957 only eliminate `term' if both sides of the IOR would do so. */
2958 temp = *pterm;
2959 left = simplify_and_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
2960 left_eliminates_term = (temp == true_rtx);
2961
2962 temp = *pterm;
2963 right = simplify_and_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2964 right_eliminates_term = (temp == true_rtx);
2965
2966 if (left_eliminates_term && right_eliminates_term)
2967 *pterm = true_rtx;
2968
2969 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2970 {
2971 newexp = attr_rtx (GET_CODE (exp), left, right);
2972
2973 exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2974 }
2975 }
2976
2977 /* Check for simplifications. Do some extra checking here since this
2978 routine is called so many times. */
2979
2980 if (exp == *pterm)
2981 return true_rtx;
2982
2983 else if (GET_CODE (exp) == NOT && XEXP (exp, 0) == *pterm)
2984 return false_rtx;
2985
2986 else if (GET_CODE (*pterm) == NOT && exp == XEXP (*pterm, 0))
2987 return false_rtx;
2988
2989 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == EQ_ATTR)
2990 {
2991 if (XSTR (exp, 0) != XSTR (*pterm, 0))
2992 return exp;
2993
2994 if (! strcmp (XSTR (exp, 1), XSTR (*pterm, 1)))
2995 return true_rtx;
2996 else
2997 return false_rtx;
2998 }
2999
3000 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
3001 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
3002 {
3003 if (XSTR (*pterm, 0) != XSTR (XEXP (exp, 0), 0))
3004 return exp;
3005
3006 if (! strcmp (XSTR (*pterm, 1), XSTR (XEXP (exp, 0), 1)))
3007 return false_rtx;
3008 else
3009 return true_rtx;
3010 }
3011
3012 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
3013 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR)
3014 {
3015 if (XSTR (exp, 0) != XSTR (XEXP (*pterm, 0), 0))
3016 return exp;
3017
3018 if (! strcmp (XSTR (exp, 1), XSTR (XEXP (*pterm, 0), 1)))
3019 return false_rtx;
3020 else
3021 *pterm = true_rtx;
3022 }
3023
3024 else if (GET_CODE (exp) == NOT && GET_CODE (*pterm) == NOT)
3025 {
3026 if (attr_equal_p (XEXP (exp, 0), XEXP (*pterm, 0)))
3027 return true_rtx;
3028 }
3029
3030 else if (GET_CODE (exp) == NOT)
3031 {
3032 if (attr_equal_p (XEXP (exp, 0), *pterm))
3033 return false_rtx;
3034 }
3035
3036 else if (GET_CODE (*pterm) == NOT)
3037 {
3038 if (attr_equal_p (XEXP (*pterm, 0), exp))
3039 return false_rtx;
3040 }
3041
3042 else if (attr_equal_p (exp, *pterm))
3043 return true_rtx;
3044
3045 return exp;
3046 }
3047 \f
3048 /* Similar to `simplify_and_tree', but for IOR trees. */
3049
3050 static rtx
3051 simplify_or_tree (exp, pterm, insn_code, insn_index)
3052 rtx exp;
3053 rtx *pterm;
3054 int insn_code, insn_index;
3055 {
3056 rtx left, right;
3057 rtx newexp;
3058 rtx temp;
3059 int left_eliminates_term, right_eliminates_term;
3060
3061 if (GET_CODE (exp) == IOR)
3062 {
3063 left = simplify_or_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
3064 right = simplify_or_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
3065 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3066 {
3067 newexp = attr_rtx (GET_CODE (exp), left, right);
3068
3069 exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3070 }
3071 }
3072
3073 else if (GET_CODE (exp) == AND)
3074 {
3075 /* For the AND case, we do the same as above, except that we can
3076 only eliminate `term' if both sides of the AND would do so. */
3077 temp = *pterm;
3078 left = simplify_or_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
3079 left_eliminates_term = (temp == false_rtx);
3080
3081 temp = *pterm;
3082 right = simplify_or_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
3083 right_eliminates_term = (temp == false_rtx);
3084
3085 if (left_eliminates_term && right_eliminates_term)
3086 *pterm = false_rtx;
3087
3088 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3089 {
3090 newexp = attr_rtx (GET_CODE (exp), left, right);
3091
3092 exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3093 }
3094 }
3095
3096 if (attr_equal_p (exp, *pterm))
3097 return false_rtx;
3098
3099 else if (GET_CODE (exp) == NOT && attr_equal_p (XEXP (exp, 0), *pterm))
3100 return true_rtx;
3101
3102 else if (GET_CODE (*pterm) == NOT && attr_equal_p (XEXP (*pterm, 0), exp))
3103 return true_rtx;
3104
3105 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
3106 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
3107 && XSTR (*pterm, 0) == XSTR (XEXP (exp, 0), 0))
3108 *pterm = false_rtx;
3109
3110 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
3111 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR
3112 && XSTR (exp, 0) == XSTR (XEXP (*pterm, 0), 0))
3113 return false_rtx;
3114
3115 return exp;
3116 }
3117 \f
3118 /* Given an expression, see if it can be simplified for a particular insn
3119 code based on the values of other attributes being tested. This can
3120 eliminate nested get_attr_... calls.
3121
3122 Note that if an endless recursion is specified in the patterns, the
3123 optimization will loop. However, it will do so in precisely the cases where
3124 an infinite recursion loop could occur during compilation. It's better that
3125 it occurs here! */
3126
3127 static rtx
3128 simplify_test_exp (exp, insn_code, insn_index)
3129 rtx exp;
3130 int insn_code, insn_index;
3131 {
3132 rtx left, right;
3133 struct attr_desc *attr;
3134 struct attr_value *av;
3135 struct insn_ent *ie;
3136 int i;
3137 rtx newexp = exp;
3138 char *spacer = (char *) obstack_finish (rtl_obstack);
3139
3140 /* Don't re-simplify something we already simplified. */
3141 if (RTX_UNCHANGING_P (exp) || MEM_IN_STRUCT_P (exp))
3142 return exp;
3143
3144 switch (GET_CODE (exp))
3145 {
3146 case AND:
3147 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
3148 SIMPLIFY_ALTERNATIVE (left);
3149 if (left == false_rtx)
3150 {
3151 if (!ggc_p)
3152 obstack_free (rtl_obstack, spacer);
3153 return false_rtx;
3154 }
3155 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
3156 SIMPLIFY_ALTERNATIVE (right);
3157 if (left == false_rtx)
3158 {
3159 if (!ggc_p)
3160 obstack_free (rtl_obstack, spacer);
3161 return false_rtx;
3162 }
3163
3164 /* If either side is an IOR and we have (eq_attr "alternative" ..")
3165 present on both sides, apply the distributive law since this will
3166 yield simplifications. */
3167 if ((GET_CODE (left) == IOR || GET_CODE (right) == IOR)
3168 && compute_alternative_mask (left, IOR)
3169 && compute_alternative_mask (right, IOR))
3170 {
3171 if (GET_CODE (left) == IOR)
3172 {
3173 rtx tem = left;
3174 left = right;
3175 right = tem;
3176 }
3177
3178 newexp = attr_rtx (IOR,
3179 attr_rtx (AND, left, XEXP (right, 0)),
3180 attr_rtx (AND, left, XEXP (right, 1)));
3181
3182 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3183 }
3184
3185 /* Try with the term on both sides. */
3186 right = simplify_and_tree (right, &left, insn_code, insn_index);
3187 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
3188 left = simplify_and_tree (left, &right, insn_code, insn_index);
3189
3190 if (left == false_rtx || right == false_rtx)
3191 {
3192 if (!ggc_p)
3193 obstack_free (rtl_obstack, spacer);
3194 return false_rtx;
3195 }
3196 else if (left == true_rtx)
3197 {
3198 return right;
3199 }
3200 else if (right == true_rtx)
3201 {
3202 return left;
3203 }
3204 /* See if all or all but one of the insn's alternatives are specified
3205 in this tree. Optimize if so. */
3206
3207 else if (insn_code >= 0
3208 && (GET_CODE (left) == AND
3209 || (GET_CODE (left) == NOT
3210 && GET_CODE (XEXP (left, 0)) == EQ_ATTR
3211 && XSTR (XEXP (left, 0), 0) == alternative_name)
3212 || GET_CODE (right) == AND
3213 || (GET_CODE (right) == NOT
3214 && GET_CODE (XEXP (right, 0)) == EQ_ATTR
3215 && XSTR (XEXP (right, 0), 0) == alternative_name)))
3216 {
3217 i = compute_alternative_mask (exp, AND);
3218 if (i & ~insn_alternatives[insn_code])
3219 fatal ("Invalid alternative specified for pattern number %d",
3220 insn_index);
3221
3222 /* If all alternatives are excluded, this is false. */
3223 i ^= insn_alternatives[insn_code];
3224 if (i == 0)
3225 return false_rtx;
3226 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
3227 {
3228 /* If just one excluded, AND a comparison with that one to the
3229 front of the tree. The others will be eliminated by
3230 optimization. We do not want to do this if the insn has one
3231 alternative and we have tested none of them! */
3232 left = make_alternative_compare (i);
3233 right = simplify_and_tree (exp, &left, insn_code, insn_index);
3234 newexp = attr_rtx (AND, left, right);
3235
3236 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3237 }
3238 }
3239
3240 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3241 {
3242 newexp = attr_rtx (AND, left, right);
3243 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3244 }
3245 break;
3246
3247 case IOR:
3248 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
3249 SIMPLIFY_ALTERNATIVE (left);
3250 if (left == true_rtx)
3251 {
3252 if (!ggc_p)
3253 obstack_free (rtl_obstack, spacer);
3254 return true_rtx;
3255 }
3256 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
3257 SIMPLIFY_ALTERNATIVE (right);
3258 if (right == true_rtx)
3259 {
3260 if (!ggc_p)
3261 obstack_free (rtl_obstack, spacer);
3262 return true_rtx;
3263 }
3264
3265 right = simplify_or_tree (right, &left, insn_code, insn_index);
3266 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
3267 left = simplify_or_tree (left, &right, insn_code, insn_index);
3268
3269 if (right == true_rtx || left == true_rtx)
3270 {
3271 if (!ggc_p)
3272 obstack_free (rtl_obstack, spacer);
3273 return true_rtx;
3274 }
3275 else if (left == false_rtx)
3276 {
3277 return right;
3278 }
3279 else if (right == false_rtx)
3280 {
3281 return left;
3282 }
3283
3284 /* Test for simple cases where the distributive law is useful. I.e.,
3285 convert (ior (and (x) (y))
3286 (and (x) (z)))
3287 to (and (x)
3288 (ior (y) (z)))
3289 */
3290
3291 else if (GET_CODE (left) == AND && GET_CODE (right) == AND
3292 && attr_equal_p (XEXP (left, 0), XEXP (right, 0)))
3293 {
3294 newexp = attr_rtx (IOR, XEXP (left, 1), XEXP (right, 1));
3295
3296 left = XEXP (left, 0);
3297 right = newexp;
3298 newexp = attr_rtx (AND, left, right);
3299 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3300 }
3301
3302 /* See if all or all but one of the insn's alternatives are specified
3303 in this tree. Optimize if so. */
3304
3305 else if (insn_code >= 0
3306 && (GET_CODE (left) == IOR
3307 || (GET_CODE (left) == EQ_ATTR
3308 && XSTR (left, 0) == alternative_name)
3309 || GET_CODE (right) == IOR
3310 || (GET_CODE (right) == EQ_ATTR
3311 && XSTR (right, 0) == alternative_name)))
3312 {
3313 i = compute_alternative_mask (exp, IOR);
3314 if (i & ~insn_alternatives[insn_code])
3315 fatal ("Invalid alternative specified for pattern number %d",
3316 insn_index);
3317
3318 /* If all alternatives are included, this is true. */
3319 i ^= insn_alternatives[insn_code];
3320 if (i == 0)
3321 return true_rtx;
3322 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
3323 {
3324 /* If just one excluded, IOR a comparison with that one to the
3325 front of the tree. The others will be eliminated by
3326 optimization. We do not want to do this if the insn has one
3327 alternative and we have tested none of them! */
3328 left = make_alternative_compare (i);
3329 right = simplify_and_tree (exp, &left, insn_code, insn_index);
3330 newexp = attr_rtx (IOR, attr_rtx (NOT, left), right);
3331
3332 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3333 }
3334 }
3335
3336 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3337 {
3338 newexp = attr_rtx (IOR, left, right);
3339 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3340 }
3341 break;
3342
3343 case NOT:
3344 if (GET_CODE (XEXP (exp, 0)) == NOT)
3345 {
3346 left = SIMPLIFY_TEST_EXP (XEXP (XEXP (exp, 0), 0),
3347 insn_code, insn_index);
3348 SIMPLIFY_ALTERNATIVE (left);
3349 return left;
3350 }
3351
3352 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
3353 SIMPLIFY_ALTERNATIVE (left);
3354 if (GET_CODE (left) == NOT)
3355 return XEXP (left, 0);
3356
3357 if (left == false_rtx)
3358 {
3359 if (!ggc_p)
3360 obstack_free (rtl_obstack, spacer);
3361 return true_rtx;
3362 }
3363 else if (left == true_rtx)
3364 {
3365 if (!ggc_p)
3366 obstack_free (rtl_obstack, spacer);
3367 return false_rtx;
3368 }
3369
3370 /* Try to apply De`Morgan's laws. */
3371 else if (GET_CODE (left) == IOR)
3372 {
3373 newexp = attr_rtx (AND,
3374 attr_rtx (NOT, XEXP (left, 0)),
3375 attr_rtx (NOT, XEXP (left, 1)));
3376
3377 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3378 }
3379 else if (GET_CODE (left) == AND)
3380 {
3381 newexp = attr_rtx (IOR,
3382 attr_rtx (NOT, XEXP (left, 0)),
3383 attr_rtx (NOT, XEXP (left, 1)));
3384
3385 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3386 }
3387 else if (left != XEXP (exp, 0))
3388 {
3389 newexp = attr_rtx (NOT, left);
3390 }
3391 break;
3392
3393 case EQ_ATTR:
3394 if (current_alternative_string && XSTR (exp, 0) == alternative_name)
3395 return (XSTR (exp, 1) == current_alternative_string
3396 ? true_rtx : false_rtx);
3397
3398 /* Look at the value for this insn code in the specified attribute.
3399 We normally can replace this comparison with the condition that
3400 would give this insn the values being tested for. */
3401 if (XSTR (exp, 0) != alternative_name
3402 && (attr = find_attr (XSTR (exp, 0), 0)) != NULL)
3403 for (av = attr->first_value; av; av = av->next)
3404 for (ie = av->first_insn; ie; ie = ie->next)
3405 if (ie->insn_code == insn_code)
3406 return evaluate_eq_attr (exp, av->value, insn_code, insn_index);
3407 break;
3408
3409 default:
3410 break;
3411 }
3412
3413 /* We have already simplified this expression. Simplifying it again
3414 won't buy anything unless we weren't given a valid insn code
3415 to process (i.e., we are canonicalizing something.). */
3416 if (insn_code != -2 /* Seems wrong: && current_alternative_string. */
3417 && ! RTX_UNCHANGING_P (newexp))
3418 return copy_rtx_unchanging (newexp);
3419
3420 return newexp;
3421 }
3422 \f
3423 /* Optimize the attribute lists by seeing if we can determine conditional
3424 values from the known values of other attributes. This will save subroutine
3425 calls during the compilation. */
3426
3427 static void
3428 optimize_attrs ()
3429 {
3430 struct attr_desc *attr;
3431 struct attr_value *av;
3432 struct insn_ent *ie;
3433 rtx newexp;
3434 int something_changed = 1;
3435 int i;
3436 struct attr_value_list { struct attr_value *av;
3437 struct insn_ent *ie;
3438 struct attr_desc * attr;
3439 struct attr_value_list *next; };
3440 struct attr_value_list **insn_code_values;
3441 struct attr_value_list *ivbuf;
3442 struct attr_value_list *iv;
3443
3444 /* For each insn code, make a list of all the insn_ent's for it,
3445 for all values for all attributes. */
3446
3447 if (num_insn_ents == 0)
3448 return;
3449
3450 /* Make 2 extra elements, for "code" values -2 and -1. */
3451 insn_code_values
3452 = (struct attr_value_list **) alloca ((insn_code_number + 2)
3453 * sizeof (struct attr_value_list *));
3454 bzero ((char *) insn_code_values,
3455 (insn_code_number + 2) * sizeof (struct attr_value_list *));
3456
3457 /* Offset the table address so we can index by -2 or -1. */
3458 insn_code_values += 2;
3459
3460 /* Allocate the attr_value_list structures using xmalloc rather than
3461 alloca, because using alloca can overflow the maximum permitted
3462 stack limit on SPARC Lynx. */
3463 iv = ivbuf = ((struct attr_value_list *)
3464 xmalloc (num_insn_ents * sizeof (struct attr_value_list)));
3465
3466 for (i = 0; i < MAX_ATTRS_INDEX; i++)
3467 for (attr = attrs[i]; attr; attr = attr->next)
3468 for (av = attr->first_value; av; av = av->next)
3469 for (ie = av->first_insn; ie; ie = ie->next)
3470 {
3471 iv->attr = attr;
3472 iv->av = av;
3473 iv->ie = ie;
3474 iv->next = insn_code_values[ie->insn_code];
3475 insn_code_values[ie->insn_code] = iv;
3476 iv++;
3477 }
3478
3479 /* Sanity check on num_insn_ents. */
3480 if (iv != ivbuf + num_insn_ents)
3481 abort ();
3482
3483 /* Process one insn code at a time. */
3484 for (i = -2; i < insn_code_number; i++)
3485 {
3486 /* Clear the MEM_IN_STRUCT_P flag everywhere relevant.
3487 We use it to mean "already simplified for this insn". */
3488 for (iv = insn_code_values[i]; iv; iv = iv->next)
3489 clear_struct_flag (iv->av->value);
3490
3491 /* Loop until nothing changes for one iteration. */
3492 something_changed = 1;
3493 while (something_changed)
3494 {
3495 something_changed = 0;
3496 for (iv = insn_code_values[i]; iv; iv = iv->next)
3497 {
3498 struct obstack *old = rtl_obstack;
3499 char *spacer = (char *) obstack_finish (temp_obstack);
3500
3501 attr = iv->attr;
3502 av = iv->av;
3503 ie = iv->ie;
3504 if (GET_CODE (av->value) != COND)
3505 continue;
3506
3507 rtl_obstack = temp_obstack;
3508 #if 0 /* This was intended as a speed up, but it was slower. */
3509 if (insn_n_alternatives[ie->insn_code] > 6
3510 && count_sub_rtxs (av->value, 200) >= 200)
3511 newexp = simplify_by_alternatives (av->value, ie->insn_code,
3512 ie->insn_index);
3513 else
3514 #endif
3515 newexp = simplify_cond (av->value, ie->insn_code,
3516 ie->insn_index);
3517
3518 rtl_obstack = old;
3519 if (newexp != av->value)
3520 {
3521 newexp = attr_copy_rtx (newexp);
3522 remove_insn_ent (av, ie);
3523 av = get_attr_value (newexp, attr, ie->insn_code);
3524 iv->av = av;
3525 insert_insn_ent (av, ie);
3526 something_changed = 1;
3527 }
3528 if (!ggc_p)
3529 obstack_free (temp_obstack, spacer);
3530 }
3531 }
3532 }
3533
3534 free (ivbuf);
3535 }
3536
3537 #if 0
3538 static rtx
3539 simplify_by_alternatives (exp, insn_code, insn_index)
3540 rtx exp;
3541 int insn_code, insn_index;
3542 {
3543 int i;
3544 int len = insn_n_alternatives[insn_code];
3545 rtx newexp = rtx_alloc (COND);
3546 rtx ultimate;
3547
3548
3549 XVEC (newexp, 0) = rtvec_alloc (len * 2);
3550
3551 /* It will not matter what value we use as the default value
3552 of the new COND, since that default will never be used.
3553 Choose something of the right type. */
3554 for (ultimate = exp; GET_CODE (ultimate) == COND;)
3555 ultimate = XEXP (ultimate, 1);
3556 XEXP (newexp, 1) = ultimate;
3557
3558 for (i = 0; i < insn_n_alternatives[insn_code]; i++)
3559 {
3560 current_alternative_string = attr_numeral (i);
3561 XVECEXP (newexp, 0, i * 2) = make_alternative_compare (1 << i);
3562 XVECEXP (newexp, 0, i * 2 + 1)
3563 = simplify_cond (exp, insn_code, insn_index);
3564 }
3565
3566 current_alternative_string = 0;
3567 return simplify_cond (newexp, insn_code, insn_index);
3568 }
3569 #endif
3570 \f
3571 /* If EXP is a suitable expression, reorganize it by constructing an
3572 equivalent expression that is a COND with the tests being all combinations
3573 of attribute values and the values being simple constants. */
3574
3575 static rtx
3576 simplify_by_exploding (exp)
3577 rtx exp;
3578 {
3579 rtx list = 0, link, condexp, defval = NULL_RTX;
3580 struct dimension *space;
3581 rtx *condtest, *condval;
3582 int i, j, total, ndim = 0;
3583 int most_tests, num_marks, new_marks;
3584
3585 /* Locate all the EQ_ATTR expressions. */
3586 if (! find_and_mark_used_attributes (exp, &list, &ndim) || ndim == 0)
3587 {
3588 unmark_used_attributes (list, 0, 0);
3589 return exp;
3590 }
3591
3592 /* Create an attribute space from the list of used attributes. For each
3593 dimension in the attribute space, record the attribute, list of values
3594 used, and number of values used. Add members to the list of values to
3595 cover the domain of the attribute. This makes the expanded COND form
3596 order independent. */
3597
3598 space = (struct dimension *) alloca (ndim * sizeof (struct dimension));
3599
3600 total = 1;
3601 for (ndim = 0; list; ndim++)
3602 {
3603 /* Pull the first attribute value from the list and record that
3604 attribute as another dimension in the attribute space. */
3605 char *name = XSTR (XEXP (list, 0), 0);
3606 rtx *prev;
3607
3608 if ((space[ndim].attr = find_attr (name, 0)) == 0
3609 || space[ndim].attr->is_numeric)
3610 {
3611 unmark_used_attributes (list, space, ndim);
3612 return exp;
3613 }
3614
3615 /* Add all remaining attribute values that refer to this attribute. */
3616 space[ndim].num_values = 0;
3617 space[ndim].values = 0;
3618 prev = &list;
3619 for (link = list; link; link = *prev)
3620 if (! strcmp (XSTR (XEXP (link, 0), 0), name))
3621 {
3622 space[ndim].num_values++;
3623 *prev = XEXP (link, 1);
3624 XEXP (link, 1) = space[ndim].values;
3625 space[ndim].values = link;
3626 }
3627 else
3628 prev = &XEXP (link, 1);
3629
3630 /* Add sufficient members to the list of values to make the list
3631 mutually exclusive and record the total size of the attribute
3632 space. */
3633 total *= add_values_to_cover (&space[ndim]);
3634 }
3635
3636 /* Sort the attribute space so that the attributes go from non-constant
3637 to constant and from most values to least values. */
3638 for (i = 0; i < ndim; i++)
3639 for (j = ndim - 1; j > i; j--)
3640 if ((space[j-1].attr->is_const && !space[j].attr->is_const)
3641 || space[j-1].num_values < space[j].num_values)
3642 {
3643 struct dimension tmp;
3644 tmp = space[j];
3645 space[j] = space[j-1];
3646 space[j-1] = tmp;
3647 }
3648
3649 /* Establish the initial current value. */
3650 for (i = 0; i < ndim; i++)
3651 space[i].current_value = space[i].values;
3652
3653 condtest = (rtx *) alloca (total * sizeof (rtx));
3654 condval = (rtx *) alloca (total * sizeof (rtx));
3655
3656 /* Expand the tests and values by iterating over all values in the
3657 attribute space. */
3658 for (i = 0;; i++)
3659 {
3660 condtest[i] = test_for_current_value (space, ndim);
3661 condval[i] = simplify_with_current_value (exp, space, ndim);
3662 if (! increment_current_value (space, ndim))
3663 break;
3664 }
3665 if (i != total - 1)
3666 abort ();
3667
3668 /* We are now finished with the original expression. */
3669 unmark_used_attributes (0, space, ndim);
3670
3671 /* Find the most used constant value and make that the default. */
3672 most_tests = -1;
3673 for (i = num_marks = 0; i < total; i++)
3674 if (GET_CODE (condval[i]) == CONST_STRING
3675 && ! MEM_VOLATILE_P (condval[i]))
3676 {
3677 /* Mark the unmarked constant value and count how many are marked. */
3678 MEM_VOLATILE_P (condval[i]) = 1;
3679 for (j = new_marks = 0; j < total; j++)
3680 if (GET_CODE (condval[j]) == CONST_STRING
3681 && MEM_VOLATILE_P (condval[j]))
3682 new_marks++;
3683 if (new_marks - num_marks > most_tests)
3684 {
3685 most_tests = new_marks - num_marks;
3686 defval = condval[i];
3687 }
3688 num_marks = new_marks;
3689 }
3690 /* Clear all the marks. */
3691 for (i = 0; i < total; i++)
3692 MEM_VOLATILE_P (condval[i]) = 0;
3693
3694 /* Give up if nothing is constant. */
3695 if (num_marks == 0)
3696 return exp;
3697
3698 /* If all values are the default, use that. */
3699 if (total == most_tests)
3700 return defval;
3701
3702 /* Make a COND with the most common constant value the default. (A more
3703 complex method where tests with the same value were combined didn't
3704 seem to improve things.) */
3705 condexp = rtx_alloc (COND);
3706 XVEC (condexp, 0) = rtvec_alloc ((total - most_tests) * 2);
3707 XEXP (condexp, 1) = defval;
3708 for (i = j = 0; i < total; i++)
3709 if (condval[i] != defval)
3710 {
3711 XVECEXP (condexp, 0, 2 * j) = condtest[i];
3712 XVECEXP (condexp, 0, 2 * j + 1) = condval[i];
3713 j++;
3714 }
3715
3716 return condexp;
3717 }
3718
3719 /* Set the MEM_VOLATILE_P flag for all EQ_ATTR expressions in EXP and
3720 verify that EXP can be simplified to a constant term if all the EQ_ATTR
3721 tests have known value. */
3722
3723 static int
3724 find_and_mark_used_attributes (exp, terms, nterms)
3725 rtx exp, *terms;
3726 int *nterms;
3727 {
3728 int i;
3729
3730 switch (GET_CODE (exp))
3731 {
3732 case EQ_ATTR:
3733 if (! MEM_VOLATILE_P (exp))
3734 {
3735 rtx link = rtx_alloc (EXPR_LIST);
3736 XEXP (link, 0) = exp;
3737 XEXP (link, 1) = *terms;
3738 *terms = link;
3739 *nterms += 1;
3740 MEM_VOLATILE_P (exp) = 1;
3741 }
3742 return 1;
3743
3744 case CONST_STRING:
3745 case CONST_INT:
3746 return 1;
3747
3748 case IF_THEN_ELSE:
3749 if (! find_and_mark_used_attributes (XEXP (exp, 2), terms, nterms))
3750 return 0;
3751 case IOR:
3752 case AND:
3753 if (! find_and_mark_used_attributes (XEXP (exp, 1), terms, nterms))
3754 return 0;
3755 case NOT:
3756 if (! find_and_mark_used_attributes (XEXP (exp, 0), terms, nterms))
3757 return 0;
3758 return 1;
3759
3760 case COND:
3761 for (i = 0; i < XVECLEN (exp, 0); i++)
3762 if (! find_and_mark_used_attributes (XVECEXP (exp, 0, i), terms, nterms))
3763 return 0;
3764 if (! find_and_mark_used_attributes (XEXP (exp, 1), terms, nterms))
3765 return 0;
3766 return 1;
3767
3768 default:
3769 return 0;
3770 }
3771 }
3772
3773 /* Clear the MEM_VOLATILE_P flag in all EQ_ATTR expressions on LIST and
3774 in the values of the NDIM-dimensional attribute space SPACE. */
3775
3776 static void
3777 unmark_used_attributes (list, space, ndim)
3778 rtx list;
3779 struct dimension *space;
3780 int ndim;
3781 {
3782 rtx link, exp;
3783 int i;
3784
3785 for (i = 0; i < ndim; i++)
3786 unmark_used_attributes (space[i].values, 0, 0);
3787
3788 for (link = list; link; link = XEXP (link, 1))
3789 {
3790 exp = XEXP (link, 0);
3791 if (GET_CODE (exp) == EQ_ATTR)
3792 MEM_VOLATILE_P (exp) = 0;
3793 }
3794 }
3795
3796 /* Update the attribute dimension DIM so that all values of the attribute
3797 are tested. Return the updated number of values. */
3798
3799 static int
3800 add_values_to_cover (dim)
3801 struct dimension *dim;
3802 {
3803 struct attr_value *av;
3804 rtx exp, link, *prev;
3805 int nalt = 0;
3806
3807 for (av = dim->attr->first_value; av; av = av->next)
3808 if (GET_CODE (av->value) == CONST_STRING)
3809 nalt++;
3810
3811 if (nalt < dim->num_values)
3812 abort ();
3813 else if (nalt == dim->num_values)
3814 ; /* Ok. */
3815 else if (nalt * 2 < dim->num_values * 3)
3816 {
3817 /* Most all the values of the attribute are used, so add all the unused
3818 values. */
3819 prev = &dim->values;
3820 for (link = dim->values; link; link = *prev)
3821 prev = &XEXP (link, 1);
3822
3823 for (av = dim->attr->first_value; av; av = av->next)
3824 if (GET_CODE (av->value) == CONST_STRING)
3825 {
3826 exp = attr_eq (dim->attr->name, XSTR (av->value, 0));
3827 if (MEM_VOLATILE_P (exp))
3828 continue;
3829
3830 link = rtx_alloc (EXPR_LIST);
3831 XEXP (link, 0) = exp;
3832 XEXP (link, 1) = 0;
3833 *prev = link;
3834 prev = &XEXP (link, 1);
3835 }
3836 dim->num_values = nalt;
3837 }
3838 else
3839 {
3840 rtx orexp = false_rtx;
3841
3842 /* Very few values are used, so compute a mutually exclusive
3843 expression. (We could do this for numeric values if that becomes
3844 important.) */
3845 prev = &dim->values;
3846 for (link = dim->values; link; link = *prev)
3847 {
3848 orexp = insert_right_side (IOR, orexp, XEXP (link, 0), -2, -2);
3849 prev = &XEXP (link, 1);
3850 }
3851 link = rtx_alloc (EXPR_LIST);
3852 XEXP (link, 0) = attr_rtx (NOT, orexp);
3853 XEXP (link, 1) = 0;
3854 *prev = link;
3855 dim->num_values++;
3856 }
3857 return dim->num_values;
3858 }
3859
3860 /* Increment the current value for the NDIM-dimensional attribute space SPACE
3861 and return FALSE if the increment overflowed. */
3862
3863 static int
3864 increment_current_value (space, ndim)
3865 struct dimension *space;
3866 int ndim;
3867 {
3868 int i;
3869
3870 for (i = ndim - 1; i >= 0; i--)
3871 {
3872 if ((space[i].current_value = XEXP (space[i].current_value, 1)) == 0)
3873 space[i].current_value = space[i].values;
3874 else
3875 return 1;
3876 }
3877 return 0;
3878 }
3879
3880 /* Construct an expression corresponding to the current value for the
3881 NDIM-dimensional attribute space SPACE. */
3882
3883 static rtx
3884 test_for_current_value (space, ndim)
3885 struct dimension *space;
3886 int ndim;
3887 {
3888 int i;
3889 rtx exp = true_rtx;
3890
3891 for (i = 0; i < ndim; i++)
3892 exp = insert_right_side (AND, exp, XEXP (space[i].current_value, 0),
3893 -2, -2);
3894
3895 return exp;
3896 }
3897
3898 /* Given the current value of the NDIM-dimensional attribute space SPACE,
3899 set the corresponding EQ_ATTR expressions to that value and reduce
3900 the expression EXP as much as possible. On input [and output], all
3901 known EQ_ATTR expressions are set to FALSE. */
3902
3903 static rtx
3904 simplify_with_current_value (exp, space, ndim)
3905 rtx exp;
3906 struct dimension *space;
3907 int ndim;
3908 {
3909 int i;
3910 rtx x;
3911
3912 /* Mark each current value as TRUE. */
3913 for (i = 0; i < ndim; i++)
3914 {
3915 x = XEXP (space[i].current_value, 0);
3916 if (GET_CODE (x) == EQ_ATTR)
3917 MEM_VOLATILE_P (x) = 0;
3918 }
3919
3920 exp = simplify_with_current_value_aux (exp);
3921
3922 /* Change each current value back to FALSE. */
3923 for (i = 0; i < ndim; i++)
3924 {
3925 x = XEXP (space[i].current_value, 0);
3926 if (GET_CODE (x) == EQ_ATTR)
3927 MEM_VOLATILE_P (x) = 1;
3928 }
3929
3930 return exp;
3931 }
3932
3933 /* Reduce the expression EXP based on the MEM_VOLATILE_P settings of
3934 all EQ_ATTR expressions. */
3935
3936 static rtx
3937 simplify_with_current_value_aux (exp)
3938 rtx exp;
3939 {
3940 register int i;
3941 rtx cond;
3942
3943 switch (GET_CODE (exp))
3944 {
3945 case EQ_ATTR:
3946 if (MEM_VOLATILE_P (exp))
3947 return false_rtx;
3948 else
3949 return true_rtx;
3950 case CONST_STRING:
3951 case CONST_INT:
3952 return exp;
3953
3954 case IF_THEN_ELSE:
3955 cond = simplify_with_current_value_aux (XEXP (exp, 0));
3956 if (cond == true_rtx)
3957 return simplify_with_current_value_aux (XEXP (exp, 1));
3958 else if (cond == false_rtx)
3959 return simplify_with_current_value_aux (XEXP (exp, 2));
3960 else
3961 return attr_rtx (IF_THEN_ELSE, cond,
3962 simplify_with_current_value_aux (XEXP (exp, 1)),
3963 simplify_with_current_value_aux (XEXP (exp, 2)));
3964
3965 case IOR:
3966 cond = simplify_with_current_value_aux (XEXP (exp, 1));
3967 if (cond == true_rtx)
3968 return cond;
3969 else if (cond == false_rtx)
3970 return simplify_with_current_value_aux (XEXP (exp, 0));
3971 else
3972 return attr_rtx (IOR, cond,
3973 simplify_with_current_value_aux (XEXP (exp, 0)));
3974
3975 case AND:
3976 cond = simplify_with_current_value_aux (XEXP (exp, 1));
3977 if (cond == true_rtx)
3978 return simplify_with_current_value_aux (XEXP (exp, 0));
3979 else if (cond == false_rtx)
3980 return cond;
3981 else
3982 return attr_rtx (AND, cond,
3983 simplify_with_current_value_aux (XEXP (exp, 0)));
3984
3985 case NOT:
3986 cond = simplify_with_current_value_aux (XEXP (exp, 0));
3987 if (cond == true_rtx)
3988 return false_rtx;
3989 else if (cond == false_rtx)
3990 return true_rtx;
3991 else
3992 return attr_rtx (NOT, cond);
3993
3994 case COND:
3995 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3996 {
3997 cond = simplify_with_current_value_aux (XVECEXP (exp, 0, i));
3998 if (cond == true_rtx)
3999 return simplify_with_current_value_aux (XVECEXP (exp, 0, i + 1));
4000 else if (cond == false_rtx)
4001 continue;
4002 else
4003 abort (); /* With all EQ_ATTR's of known value, a case should
4004 have been selected. */
4005 }
4006 return simplify_with_current_value_aux (XEXP (exp, 1));
4007
4008 default:
4009 abort ();
4010 }
4011 }
4012 \f
4013 /* Clear the MEM_IN_STRUCT_P flag in EXP and its subexpressions. */
4014
4015 static void
4016 clear_struct_flag (x)
4017 rtx x;
4018 {
4019 register int i;
4020 register int j;
4021 register enum rtx_code code;
4022 register const char *fmt;
4023
4024 MEM_IN_STRUCT_P (x) = 0;
4025 if (RTX_UNCHANGING_P (x))
4026 return;
4027
4028 code = GET_CODE (x);
4029
4030 switch (code)
4031 {
4032 case REG:
4033 case QUEUED:
4034 case CONST_INT:
4035 case CONST_DOUBLE:
4036 case SYMBOL_REF:
4037 case CODE_LABEL:
4038 case PC:
4039 case CC0:
4040 case EQ_ATTR:
4041 case ATTR_FLAG:
4042 return;
4043
4044 default:
4045 break;
4046 }
4047
4048 /* Compare the elements. If any pair of corresponding elements
4049 fail to match, return 0 for the whole things. */
4050
4051 fmt = GET_RTX_FORMAT (code);
4052 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
4053 {
4054 switch (fmt[i])
4055 {
4056 case 'V':
4057 case 'E':
4058 for (j = 0; j < XVECLEN (x, i); j++)
4059 clear_struct_flag (XVECEXP (x, i, j));
4060 break;
4061
4062 case 'e':
4063 clear_struct_flag (XEXP (x, i));
4064 break;
4065 }
4066 }
4067 }
4068
4069 /* Return the number of RTX objects making up the expression X.
4070 But if we count more than MAX objects, stop counting. */
4071
4072 static int
4073 count_sub_rtxs (x, max)
4074 rtx x;
4075 int max;
4076 {
4077 register int i;
4078 register int j;
4079 register enum rtx_code code;
4080 register const char *fmt;
4081 int total = 0;
4082
4083 code = GET_CODE (x);
4084
4085 switch (code)
4086 {
4087 case REG:
4088 case QUEUED:
4089 case CONST_INT:
4090 case CONST_DOUBLE:
4091 case SYMBOL_REF:
4092 case CODE_LABEL:
4093 case PC:
4094 case CC0:
4095 case EQ_ATTR:
4096 case ATTR_FLAG:
4097 return 1;
4098
4099 default:
4100 break;
4101 }
4102
4103 /* Compare the elements. If any pair of corresponding elements
4104 fail to match, return 0 for the whole things. */
4105
4106 fmt = GET_RTX_FORMAT (code);
4107 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
4108 {
4109 if (total >= max)
4110 return total;
4111
4112 switch (fmt[i])
4113 {
4114 case 'V':
4115 case 'E':
4116 for (j = 0; j < XVECLEN (x, i); j++)
4117 total += count_sub_rtxs (XVECEXP (x, i, j), max);
4118 break;
4119
4120 case 'e':
4121 total += count_sub_rtxs (XEXP (x, i), max);
4122 break;
4123 }
4124 }
4125 return total;
4126
4127 }
4128 \f
4129 /* Create table entries for DEFINE_ATTR. */
4130
4131 static void
4132 gen_attr (exp)
4133 rtx exp;
4134 {
4135 struct attr_desc *attr;
4136 struct attr_value *av;
4137 char *name_ptr;
4138 char *p;
4139
4140 /* Make a new attribute structure. Check for duplicate by looking at
4141 attr->default_val, since it is initialized by this routine. */
4142 attr = find_attr (XSTR (exp, 0), 1);
4143 if (attr->default_val)
4144 fatal ("Duplicate definition for `%s' attribute", attr->name);
4145
4146 if (*XSTR (exp, 1) == '\0')
4147 attr->is_numeric = 1;
4148 else
4149 {
4150 name_ptr = XSTR (exp, 1);
4151 while ((p = next_comma_elt (&name_ptr)) != NULL)
4152 {
4153 av = (struct attr_value *) oballoc (sizeof (struct attr_value));
4154 av->value = attr_rtx (CONST_STRING, p);
4155 av->next = attr->first_value;
4156 attr->first_value = av;
4157 av->first_insn = NULL;
4158 av->num_insns = 0;
4159 av->has_asm_insn = 0;
4160 }
4161 }
4162
4163 if (GET_CODE (XEXP (exp, 2)) == CONST)
4164 {
4165 attr->is_const = 1;
4166 if (attr->is_numeric)
4167 fatal ("Constant attributes may not take numeric values");
4168 /* Get rid of the CONST node. It is allowed only at top-level. */
4169 XEXP (exp, 2) = XEXP (XEXP (exp, 2), 0);
4170 }
4171
4172 if (! strcmp (attr->name, "length") && ! attr->is_numeric)
4173 fatal ("`length' attribute must take numeric values");
4174
4175 /* Set up the default value. */
4176 XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
4177 attr->default_val = get_attr_value (XEXP (exp, 2), attr, -2);
4178 }
4179 \f
4180 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
4181 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
4182 number of alternatives as this should be checked elsewhere. */
4183
4184 static int
4185 count_alternatives (exp)
4186 rtx exp;
4187 {
4188 int i, j, n;
4189 const char *fmt;
4190
4191 if (GET_CODE (exp) == MATCH_OPERAND)
4192 return n_comma_elts (XSTR (exp, 2));
4193
4194 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
4195 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
4196 switch (*fmt++)
4197 {
4198 case 'e':
4199 case 'u':
4200 n = count_alternatives (XEXP (exp, i));
4201 if (n)
4202 return n;
4203 break;
4204
4205 case 'E':
4206 case 'V':
4207 if (XVEC (exp, i) != NULL)
4208 for (j = 0; j < XVECLEN (exp, i); j++)
4209 {
4210 n = count_alternatives (XVECEXP (exp, i, j));
4211 if (n)
4212 return n;
4213 }
4214 }
4215
4216 return 0;
4217 }
4218 \f
4219 /* Returns non-zero if the given expression contains an EQ_ATTR with the
4220 `alternative' attribute. */
4221
4222 static int
4223 compares_alternatives_p (exp)
4224 rtx exp;
4225 {
4226 int i, j;
4227 const char *fmt;
4228
4229 if (GET_CODE (exp) == EQ_ATTR && XSTR (exp, 0) == alternative_name)
4230 return 1;
4231
4232 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
4233 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
4234 switch (*fmt++)
4235 {
4236 case 'e':
4237 case 'u':
4238 if (compares_alternatives_p (XEXP (exp, i)))
4239 return 1;
4240 break;
4241
4242 case 'E':
4243 for (j = 0; j < XVECLEN (exp, i); j++)
4244 if (compares_alternatives_p (XVECEXP (exp, i, j)))
4245 return 1;
4246 break;
4247 }
4248
4249 return 0;
4250 }
4251 \f
4252 /* Returns non-zero is INNER is contained in EXP. */
4253
4254 static int
4255 contained_in_p (inner, exp)
4256 rtx inner;
4257 rtx exp;
4258 {
4259 int i, j;
4260 const char *fmt;
4261
4262 if (rtx_equal_p (inner, exp))
4263 return 1;
4264
4265 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
4266 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
4267 switch (*fmt++)
4268 {
4269 case 'e':
4270 case 'u':
4271 if (contained_in_p (inner, XEXP (exp, i)))
4272 return 1;
4273 break;
4274
4275 case 'E':
4276 for (j = 0; j < XVECLEN (exp, i); j++)
4277 if (contained_in_p (inner, XVECEXP (exp, i, j)))
4278 return 1;
4279 break;
4280 }
4281
4282 return 0;
4283 }
4284 \f
4285 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
4286
4287 static void
4288 gen_insn (exp)
4289 rtx exp;
4290 {
4291 struct insn_def *id;
4292
4293 id = (struct insn_def *) oballoc (sizeof (struct insn_def));
4294 id->next = defs;
4295 defs = id;
4296 id->def = exp;
4297
4298 switch (GET_CODE (exp))
4299 {
4300 case DEFINE_INSN:
4301 id->insn_code = insn_code_number++;
4302 id->insn_index = insn_index_number++;
4303 id->num_alternatives = count_alternatives (exp);
4304 if (id->num_alternatives == 0)
4305 id->num_alternatives = 1;
4306 id->vec_idx = 4;
4307 break;
4308
4309 case DEFINE_PEEPHOLE:
4310 id->insn_code = insn_code_number++;
4311 id->insn_index = insn_index_number++;
4312 id->num_alternatives = count_alternatives (exp);
4313 if (id->num_alternatives == 0)
4314 id->num_alternatives = 1;
4315 id->vec_idx = 3;
4316 break;
4317
4318 case DEFINE_ASM_ATTRIBUTES:
4319 id->insn_code = -1;
4320 id->insn_index = -1;
4321 id->num_alternatives = 1;
4322 id->vec_idx = 0;
4323 got_define_asm_attributes = 1;
4324 break;
4325
4326 default:
4327 abort ();
4328 }
4329 }
4330 \f
4331 /* Process a DEFINE_DELAY. Validate the vector length, check if annul
4332 true or annul false is specified, and make a `struct delay_desc'. */
4333
4334 static void
4335 gen_delay (def)
4336 rtx def;
4337 {
4338 struct delay_desc *delay;
4339 int i;
4340
4341 if (XVECLEN (def, 1) % 3 != 0)
4342 fatal ("Number of elements in DEFINE_DELAY must be multiple of three.");
4343
4344 for (i = 0; i < XVECLEN (def, 1); i += 3)
4345 {
4346 if (XVECEXP (def, 1, i + 1))
4347 have_annul_true = 1;
4348 if (XVECEXP (def, 1, i + 2))
4349 have_annul_false = 1;
4350 }
4351
4352 delay = (struct delay_desc *) oballoc (sizeof (struct delay_desc));
4353 delay->def = def;
4354 delay->num = ++num_delays;
4355 delay->next = delays;
4356 delays = delay;
4357 }
4358 \f
4359 /* Process a DEFINE_FUNCTION_UNIT.
4360
4361 This gives information about a function unit contained in the CPU.
4362 We fill in a `struct function_unit_op' and a `struct function_unit'
4363 with information used later by `expand_unit'. */
4364
4365 static void
4366 gen_unit (def)
4367 rtx def;
4368 {
4369 struct function_unit *unit;
4370 struct function_unit_op *op;
4371 char *name = XSTR (def, 0);
4372 int multiplicity = XINT (def, 1);
4373 int simultaneity = XINT (def, 2);
4374 rtx condexp = XEXP (def, 3);
4375 int ready_cost = MAX (XINT (def, 4), 1);
4376 int issue_delay = MAX (XINT (def, 5), 1);
4377
4378 /* See if we have already seen this function unit. If so, check that
4379 the multiplicity and simultaneity values are the same. If not, make
4380 a structure for this function unit. */
4381 for (unit = units; unit; unit = unit->next)
4382 if (! strcmp (unit->name, name))
4383 {
4384 if (unit->multiplicity != multiplicity
4385 || unit->simultaneity != simultaneity)
4386 fatal ("Differing specifications given for `%s' function unit.",
4387 unit->name);
4388 break;
4389 }
4390
4391 if (unit == 0)
4392 {
4393 unit = (struct function_unit *) oballoc (sizeof (struct function_unit));
4394 unit->name = name;
4395 unit->multiplicity = multiplicity;
4396 unit->simultaneity = simultaneity;
4397 unit->issue_delay.min = unit->issue_delay.max = issue_delay;
4398 unit->num = num_units++;
4399 unit->num_opclasses = 0;
4400 unit->condexp = false_rtx;
4401 unit->ops = 0;
4402 unit->next = units;
4403 units = unit;
4404 }
4405
4406 /* Make a new operation class structure entry and initialize it. */
4407 op = (struct function_unit_op *) oballoc (sizeof (struct function_unit_op));
4408 op->condexp = condexp;
4409 op->num = unit->num_opclasses++;
4410 op->ready = ready_cost;
4411 op->issue_delay = issue_delay;
4412 op->next = unit->ops;
4413 unit->ops = op;
4414 num_unit_opclasses++;
4415
4416 /* Set our issue expression based on whether or not an optional conflict
4417 vector was specified. */
4418 if (XVEC (def, 6))
4419 {
4420 /* Compute the IOR of all the specified expressions. */
4421 rtx orexp = false_rtx;
4422 int i;
4423
4424 for (i = 0; i < XVECLEN (def, 6); i++)
4425 orexp = insert_right_side (IOR, orexp, XVECEXP (def, 6, i), -2, -2);
4426
4427 op->conflict_exp = orexp;
4428 extend_range (&unit->issue_delay, 1, issue_delay);
4429 }
4430 else
4431 {
4432 op->conflict_exp = true_rtx;
4433 extend_range (&unit->issue_delay, issue_delay, issue_delay);
4434 }
4435
4436 /* Merge our conditional into that of the function unit so we can determine
4437 which insns are used by the function unit. */
4438 unit->condexp = insert_right_side (IOR, unit->condexp, op->condexp, -2, -2);
4439 }
4440 \f
4441 /* Given a piece of RTX, print a C expression to test its truth value.
4442 We use AND and IOR both for logical and bit-wise operations, so
4443 interpret them as logical unless they are inside a comparison expression.
4444 The first bit of FLAGS will be non-zero in that case.
4445
4446 Set the second bit of FLAGS to make references to attribute values use
4447 a cached local variable instead of calling a function. */
4448
4449 static void
4450 write_test_expr (exp, flags)
4451 rtx exp;
4452 int flags;
4453 {
4454 int comparison_operator = 0;
4455 RTX_CODE code;
4456 struct attr_desc *attr;
4457
4458 /* In order not to worry about operator precedence, surround our part of
4459 the expression with parentheses. */
4460
4461 printf ("(");
4462 code = GET_CODE (exp);
4463 switch (code)
4464 {
4465 /* Binary operators. */
4466 case EQ: case NE:
4467 case GE: case GT: case GEU: case GTU:
4468 case LE: case LT: case LEU: case LTU:
4469 comparison_operator = 1;
4470
4471 case PLUS: case MINUS: case MULT: case DIV: case MOD:
4472 case AND: case IOR: case XOR:
4473 case ASHIFT: case LSHIFTRT: case ASHIFTRT:
4474 write_test_expr (XEXP (exp, 0), flags | comparison_operator);
4475 switch (code)
4476 {
4477 case EQ:
4478 printf (" == ");
4479 break;
4480 case NE:
4481 printf (" != ");
4482 break;
4483 case GE:
4484 printf (" >= ");
4485 break;
4486 case GT:
4487 printf (" > ");
4488 break;
4489 case GEU:
4490 printf (" >= (unsigned) ");
4491 break;
4492 case GTU:
4493 printf (" > (unsigned) ");
4494 break;
4495 case LE:
4496 printf (" <= ");
4497 break;
4498 case LT:
4499 printf (" < ");
4500 break;
4501 case LEU:
4502 printf (" <= (unsigned) ");
4503 break;
4504 case LTU:
4505 printf (" < (unsigned) ");
4506 break;
4507 case PLUS:
4508 printf (" + ");
4509 break;
4510 case MINUS:
4511 printf (" - ");
4512 break;
4513 case MULT:
4514 printf (" * ");
4515 break;
4516 case DIV:
4517 printf (" / ");
4518 break;
4519 case MOD:
4520 printf (" %% ");
4521 break;
4522 case AND:
4523 if (flags & 1)
4524 printf (" & ");
4525 else
4526 printf (" && ");
4527 break;
4528 case IOR:
4529 if (flags & 1)
4530 printf (" | ");
4531 else
4532 printf (" || ");
4533 break;
4534 case XOR:
4535 printf (" ^ ");
4536 break;
4537 case ASHIFT:
4538 printf (" << ");
4539 break;
4540 case LSHIFTRT:
4541 case ASHIFTRT:
4542 printf (" >> ");
4543 break;
4544 default:
4545 abort ();
4546 }
4547
4548 write_test_expr (XEXP (exp, 1), flags | comparison_operator);
4549 break;
4550
4551 case NOT:
4552 /* Special-case (not (eq_attrq "alternative" "x")) */
4553 if (! (flags & 1) && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
4554 && XSTR (XEXP (exp, 0), 0) == alternative_name)
4555 {
4556 printf ("which_alternative != %s", XSTR (XEXP (exp, 0), 1));
4557 break;
4558 }
4559
4560 /* Otherwise, fall through to normal unary operator. */
4561
4562 /* Unary operators. */
4563 case ABS: case NEG:
4564 switch (code)
4565 {
4566 case NOT:
4567 if (flags & 1)
4568 printf ("~ ");
4569 else
4570 printf ("! ");
4571 break;
4572 case ABS:
4573 printf ("abs ");
4574 break;
4575 case NEG:
4576 printf ("-");
4577 break;
4578 default:
4579 abort ();
4580 }
4581
4582 write_test_expr (XEXP (exp, 0), flags);
4583 break;
4584
4585 /* Comparison test of an attribute with a value. Most of these will
4586 have been removed by optimization. Handle "alternative"
4587 specially and give error if EQ_ATTR present inside a comparison. */
4588 case EQ_ATTR:
4589 if (flags & 1)
4590 fatal ("EQ_ATTR not valid inside comparison");
4591
4592 if (XSTR (exp, 0) == alternative_name)
4593 {
4594 printf ("which_alternative == %s", XSTR (exp, 1));
4595 break;
4596 }
4597
4598 attr = find_attr (XSTR (exp, 0), 0);
4599 if (! attr) abort ();
4600
4601 /* Now is the time to expand the value of a constant attribute. */
4602 if (attr->is_const)
4603 {
4604 write_test_expr (evaluate_eq_attr (exp, attr->default_val->value,
4605 -2, -2),
4606 flags);
4607 }
4608 else
4609 {
4610 if (flags & 2)
4611 printf ("attr_%s", attr->name);
4612 else
4613 printf ("get_attr_%s (insn)", attr->name);
4614 printf (" == ");
4615 write_attr_valueq (attr, XSTR (exp, 1));
4616 }
4617 break;
4618
4619 /* Comparison test of flags for define_delays. */
4620 case ATTR_FLAG:
4621 if (flags & 1)
4622 fatal ("ATTR_FLAG not valid inside comparison");
4623 printf ("(flags & ATTR_FLAG_%s) != 0", XSTR (exp, 0));
4624 break;
4625
4626 /* See if an operand matches a predicate. */
4627 case MATCH_OPERAND:
4628 /* If only a mode is given, just ensure the mode matches the operand.
4629 If neither a mode nor predicate is given, error. */
4630 if (XSTR (exp, 1) == NULL || *XSTR (exp, 1) == '\0')
4631 {
4632 if (GET_MODE (exp) == VOIDmode)
4633 fatal ("Null MATCH_OPERAND specified as test");
4634 else
4635 printf ("GET_MODE (operands[%d]) == %smode",
4636 XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
4637 }
4638 else
4639 printf ("%s (operands[%d], %smode)",
4640 XSTR (exp, 1), XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
4641 break;
4642
4643 case MATCH_INSN:
4644 printf ("%s (insn)", XSTR (exp, 0));
4645 break;
4646
4647 /* Constant integer. */
4648 case CONST_INT:
4649 printf (HOST_WIDE_INT_PRINT_DEC, XWINT (exp, 0));
4650 break;
4651
4652 /* A random C expression. */
4653 case SYMBOL_REF:
4654 printf ("%s", XSTR (exp, 0));
4655 break;
4656
4657 /* The address of the branch target. */
4658 case MATCH_DUP:
4659 printf ("insn_addresses[INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])]",
4660 XINT (exp, 0), XINT (exp, 0), XINT (exp, 0));
4661 break;
4662
4663 case PC:
4664 /* The address of the current insn. We implement this actually as the
4665 address of the current insn for backward branches, but the last
4666 address of the next insn for forward branches, and both with
4667 adjustments that account for the worst-case possible stretching of
4668 intervening alignments between this insn and its destination. */
4669 printf("insn_current_reference_address (insn)");
4670 break;
4671
4672 case CONST_STRING:
4673 printf ("%s", XSTR (exp, 0));
4674 break;
4675
4676 case IF_THEN_ELSE:
4677 write_test_expr (XEXP (exp, 0), flags & 2);
4678 printf (" ? ");
4679 write_test_expr (XEXP (exp, 1), flags | 1);
4680 printf (" : ");
4681 write_test_expr (XEXP (exp, 2), flags | 1);
4682 break;
4683
4684 default:
4685 fatal ("bad RTX code `%s' in attribute calculation\n",
4686 GET_RTX_NAME (code));
4687 }
4688
4689 printf (")");
4690 }
4691 \f
4692 /* Given an attribute value, return the maximum CONST_STRING argument
4693 encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */
4694
4695 static int
4696 max_attr_value (exp, unknownp)
4697 rtx exp;
4698 int *unknownp;
4699 {
4700 int current_max;
4701 int i, n;
4702
4703 switch (GET_CODE (exp))
4704 {
4705 case CONST_STRING:
4706 current_max = atoi (XSTR (exp, 0));
4707 break;
4708
4709 case COND:
4710 current_max = max_attr_value (XEXP (exp, 1), unknownp);
4711 for (i = 0; i < XVECLEN (exp, 0); i += 2)
4712 {
4713 n = max_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
4714 if (n > current_max)
4715 current_max = n;
4716 }
4717 break;
4718
4719 case IF_THEN_ELSE:
4720 current_max = max_attr_value (XEXP (exp, 1), unknownp);
4721 n = max_attr_value (XEXP (exp, 2), unknownp);
4722 if (n > current_max)
4723 current_max = n;
4724 break;
4725
4726 default:
4727 *unknownp = 1;
4728 current_max = INT_MAX;
4729 break;
4730 }
4731
4732 return current_max;
4733 }
4734
4735 /* Given an attribute value, return the result of ORing together all
4736 CONST_STRING arguments encountered. Set *UNKNOWNP and return -1
4737 if the numeric value is not known. */
4738
4739 static int
4740 or_attr_value (exp, unknownp)
4741 rtx exp;
4742 int *unknownp;
4743 {
4744 int current_or;
4745 int i;
4746
4747 switch (GET_CODE (exp))
4748 {
4749 case CONST_STRING:
4750 current_or = atoi (XSTR (exp, 0));
4751 break;
4752
4753 case COND:
4754 current_or = or_attr_value (XEXP (exp, 1), unknownp);
4755 for (i = 0; i < XVECLEN (exp, 0); i += 2)
4756 current_or |= or_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
4757 break;
4758
4759 case IF_THEN_ELSE:
4760 current_or = or_attr_value (XEXP (exp, 1), unknownp);
4761 current_or |= or_attr_value (XEXP (exp, 2), unknownp);
4762 break;
4763
4764 default:
4765 *unknownp = 1;
4766 current_or = -1;
4767 break;
4768 }
4769
4770 return current_or;
4771 }
4772 \f
4773 /* Scan an attribute value, possibly a conditional, and record what actions
4774 will be required to do any conditional tests in it.
4775
4776 Specifically, set
4777 `must_extract' if we need to extract the insn operands
4778 `must_constrain' if we must compute `which_alternative'
4779 `address_used' if an address expression was used
4780 `length_used' if an (eq_attr "length" ...) was used
4781 */
4782
4783 static void
4784 walk_attr_value (exp)
4785 rtx exp;
4786 {
4787 register int i, j;
4788 register const char *fmt;
4789 RTX_CODE code;
4790
4791 if (exp == NULL)
4792 return;
4793
4794 code = GET_CODE (exp);
4795 switch (code)
4796 {
4797 case SYMBOL_REF:
4798 if (! RTX_UNCHANGING_P (exp))
4799 /* Since this is an arbitrary expression, it can look at anything.
4800 However, constant expressions do not depend on any particular
4801 insn. */
4802 must_extract = must_constrain = 1;
4803 return;
4804
4805 case MATCH_OPERAND:
4806 must_extract = 1;
4807 return;
4808
4809 case EQ_ATTR:
4810 if (XSTR (exp, 0) == alternative_name)
4811 must_extract = must_constrain = 1;
4812 else if (strcmp (XSTR (exp, 0), "length") == 0)
4813 length_used = 1;
4814 return;
4815
4816 case MATCH_DUP:
4817 must_extract = 1;
4818 address_used = 1;
4819 return;
4820
4821 case PC:
4822 address_used = 1;
4823 return;
4824
4825 case ATTR_FLAG:
4826 return;
4827
4828 default:
4829 break;
4830 }
4831
4832 for (i = 0, fmt = GET_RTX_FORMAT (code); i < GET_RTX_LENGTH (code); i++)
4833 switch (*fmt++)
4834 {
4835 case 'e':
4836 case 'u':
4837 walk_attr_value (XEXP (exp, i));
4838 break;
4839
4840 case 'E':
4841 if (XVEC (exp, i) != NULL)
4842 for (j = 0; j < XVECLEN (exp, i); j++)
4843 walk_attr_value (XVECEXP (exp, i, j));
4844 break;
4845 }
4846 }
4847 \f
4848 /* Write out a function to obtain the attribute for a given INSN. */
4849
4850 static void
4851 write_attr_get (attr)
4852 struct attr_desc *attr;
4853 {
4854 struct attr_value *av, *common_av;
4855
4856 /* Find the most used attribute value. Handle that as the `default' of the
4857 switch we will generate. */
4858 common_av = find_most_used (attr);
4859
4860 /* Write out prototype of function. */
4861 if (!attr->is_numeric)
4862 printf ("extern enum attr_%s ", attr->name);
4863 else if (attr->unsigned_p)
4864 printf ("extern unsigned int ");
4865 else
4866 printf ("extern int ");
4867 /* If the attribute name starts with a star, the remainder is the name of
4868 the subroutine to use, instead of `get_attr_...'. */
4869 if (attr->name[0] == '*')
4870 printf ("%s PROTO ((rtx));\n", &attr->name[1]);
4871 else
4872 printf ("get_attr_%s PROTO ((%s));\n", attr->name,
4873 (attr->is_const ? "void" : "rtx"));
4874
4875 /* Write out start of function, then all values with explicit `case' lines,
4876 then a `default', then the value with the most uses. */
4877 if (!attr->is_numeric)
4878 printf ("enum attr_%s\n", attr->name);
4879 else if (attr->unsigned_p)
4880 printf ("unsigned int\n");
4881 else
4882 printf ("int\n");
4883
4884 /* If the attribute name starts with a star, the remainder is the name of
4885 the subroutine to use, instead of `get_attr_...'. */
4886 if (attr->name[0] == '*')
4887 printf ("%s (insn)\n", &attr->name[1]);
4888 else if (attr->is_const == 0)
4889 printf ("get_attr_%s (insn)\n", attr->name);
4890 else
4891 {
4892 printf ("get_attr_%s ()\n", attr->name);
4893 printf ("{\n");
4894
4895 for (av = attr->first_value; av; av = av->next)
4896 if (av->num_insns != 0)
4897 write_attr_set (attr, 2, av->value, "return", ";",
4898 true_rtx, av->first_insn->insn_code,
4899 av->first_insn->insn_index);
4900
4901 printf ("}\n\n");
4902 return;
4903 }
4904
4905 printf (" rtx insn;\n");
4906 printf ("{\n");
4907
4908 if (GET_CODE (common_av->value) == FFS)
4909 {
4910 rtx p = XEXP (common_av->value, 0);
4911
4912 /* No need to emit code to abort if the insn is unrecognized; the
4913 other get_attr_foo functions will do that when we call them. */
4914
4915 write_toplevel_expr (p);
4916
4917 printf ("\n if (accum && accum == (accum & -accum))\n");
4918 printf (" {\n");
4919 printf (" int i;\n");
4920 printf (" for (i = 0; accum >>= 1; ++i) continue;\n");
4921 printf (" accum = i;\n");
4922 printf (" }\n else\n");
4923 printf (" accum = ~accum;\n");
4924 printf (" return accum;\n}\n\n");
4925 }
4926 else
4927 {
4928 printf (" switch (recog_memoized (insn))\n");
4929 printf (" {\n");
4930
4931 for (av = attr->first_value; av; av = av->next)
4932 if (av != common_av)
4933 write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
4934
4935 write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
4936 printf (" }\n}\n\n");
4937 }
4938 }
4939 \f
4940 /* Given an AND tree of known true terms (because we are inside an `if' with
4941 that as the condition or are in an `else' clause) and an expression,
4942 replace any known true terms with TRUE. Use `simplify_and_tree' to do
4943 the bulk of the work. */
4944
4945 static rtx
4946 eliminate_known_true (known_true, exp, insn_code, insn_index)
4947 rtx known_true;
4948 rtx exp;
4949 int insn_code, insn_index;
4950 {
4951 rtx term;
4952
4953 known_true = SIMPLIFY_TEST_EXP (known_true, insn_code, insn_index);
4954
4955 if (GET_CODE (known_true) == AND)
4956 {
4957 exp = eliminate_known_true (XEXP (known_true, 0), exp,
4958 insn_code, insn_index);
4959 exp = eliminate_known_true (XEXP (known_true, 1), exp,
4960 insn_code, insn_index);
4961 }
4962 else
4963 {
4964 term = known_true;
4965 exp = simplify_and_tree (exp, &term, insn_code, insn_index);
4966 }
4967
4968 return exp;
4969 }
4970 \f
4971 /* Write out a series of tests and assignment statements to perform tests and
4972 sets of an attribute value. We are passed an indentation amount and prefix
4973 and suffix strings to write around each attribute value (e.g., "return"
4974 and ";"). */
4975
4976 static void
4977 write_attr_set (attr, indent, value, prefix, suffix, known_true,
4978 insn_code, insn_index)
4979 struct attr_desc *attr;
4980 int indent;
4981 rtx value;
4982 const char *prefix;
4983 const char *suffix;
4984 rtx known_true;
4985 int insn_code, insn_index;
4986 {
4987 if (GET_CODE (value) == COND)
4988 {
4989 /* Assume the default value will be the default of the COND unless we
4990 find an always true expression. */
4991 rtx default_val = XEXP (value, 1);
4992 rtx our_known_true = known_true;
4993 rtx newexp;
4994 int first_if = 1;
4995 int i;
4996
4997 for (i = 0; i < XVECLEN (value, 0); i += 2)
4998 {
4999 rtx testexp;
5000 rtx inner_true;
5001
5002 testexp = eliminate_known_true (our_known_true,
5003 XVECEXP (value, 0, i),
5004 insn_code, insn_index);
5005 newexp = attr_rtx (NOT, testexp);
5006 newexp = insert_right_side (AND, our_known_true, newexp,
5007 insn_code, insn_index);
5008
5009 /* If the test expression is always true or if the next `known_true'
5010 expression is always false, this is the last case, so break
5011 out and let this value be the `else' case. */
5012 if (testexp == true_rtx || newexp == false_rtx)
5013 {
5014 default_val = XVECEXP (value, 0, i + 1);
5015 break;
5016 }
5017
5018 /* Compute the expression to pass to our recursive call as being
5019 known true. */
5020 inner_true = insert_right_side (AND, our_known_true,
5021 testexp, insn_code, insn_index);
5022
5023 /* If this is always false, skip it. */
5024 if (inner_true == false_rtx)
5025 continue;
5026
5027 write_indent (indent);
5028 printf ("%sif ", first_if ? "" : "else ");
5029 first_if = 0;
5030 write_test_expr (testexp, 0);
5031 printf ("\n");
5032 write_indent (indent + 2);
5033 printf ("{\n");
5034
5035 write_attr_set (attr, indent + 4,
5036 XVECEXP (value, 0, i + 1), prefix, suffix,
5037 inner_true, insn_code, insn_index);
5038 write_indent (indent + 2);
5039 printf ("}\n");
5040 our_known_true = newexp;
5041 }
5042
5043 if (! first_if)
5044 {
5045 write_indent (indent);
5046 printf ("else\n");
5047 write_indent (indent + 2);
5048 printf ("{\n");
5049 }
5050
5051 write_attr_set (attr, first_if ? indent : indent + 4, default_val,
5052 prefix, suffix, our_known_true, insn_code, insn_index);
5053
5054 if (! first_if)
5055 {
5056 write_indent (indent + 2);
5057 printf ("}\n");
5058 }
5059 }
5060 else
5061 {
5062 write_indent (indent);
5063 printf ("%s ", prefix);
5064 write_attr_value (attr, value);
5065 printf ("%s\n", suffix);
5066 }
5067 }
5068 \f
5069 /* Write out the computation for one attribute value. */
5070
5071 static void
5072 write_attr_case (attr, av, write_case_lines, prefix, suffix, indent,
5073 known_true)
5074 struct attr_desc *attr;
5075 struct attr_value *av;
5076 int write_case_lines;
5077 const char *prefix, *suffix;
5078 int indent;
5079 rtx known_true;
5080 {
5081 struct insn_ent *ie;
5082
5083 if (av->num_insns == 0)
5084 return;
5085
5086 if (av->has_asm_insn)
5087 {
5088 write_indent (indent);
5089 printf ("case -1:\n");
5090 write_indent (indent + 2);
5091 printf ("if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
5092 write_indent (indent + 2);
5093 printf (" && asm_noperands (PATTERN (insn)) < 0)\n");
5094 write_indent (indent + 2);
5095 printf (" fatal_insn_not_found (insn);\n");
5096 }
5097
5098 if (write_case_lines)
5099 {
5100 for (ie = av->first_insn; ie; ie = ie->next)
5101 if (ie->insn_code != -1)
5102 {
5103 write_indent (indent);
5104 printf ("case %d:\n", ie->insn_code);
5105 }
5106 }
5107 else
5108 {
5109 write_indent (indent);
5110 printf ("default:\n");
5111 }
5112
5113 /* See what we have to do to output this value. */
5114 must_extract = must_constrain = address_used = 0;
5115 walk_attr_value (av->value);
5116
5117 if (must_extract)
5118 {
5119 write_indent (indent + 2);
5120 printf ("extract_insn (insn);\n");
5121 }
5122
5123 if (must_constrain)
5124 {
5125 #ifdef REGISTER_CONSTRAINTS
5126 write_indent (indent + 2);
5127 printf ("if (! constrain_operands (reload_completed))\n");
5128 write_indent (indent + 2);
5129 printf (" fatal_insn_not_found (insn);\n");
5130 #endif
5131 }
5132
5133 write_attr_set (attr, indent + 2, av->value, prefix, suffix,
5134 known_true, av->first_insn->insn_code,
5135 av->first_insn->insn_index);
5136
5137 if (strncmp (prefix, "return", 6))
5138 {
5139 write_indent (indent + 2);
5140 printf ("break;\n");
5141 }
5142 printf ("\n");
5143 }
5144 \f
5145 /* Search for uses of non-const attributes and write code to cache them. */
5146
5147 static int
5148 write_expr_attr_cache (p, attr)
5149 rtx p;
5150 struct attr_desc *attr;
5151 {
5152 const char *fmt;
5153 int i, ie, j, je;
5154
5155 if (GET_CODE (p) == EQ_ATTR)
5156 {
5157 if (XSTR (p, 0) != attr->name)
5158 return 0;
5159
5160 if (!attr->is_numeric)
5161 printf (" register enum attr_%s ", attr->name);
5162 else if (attr->unsigned_p)
5163 printf (" register unsigned int ");
5164 else
5165 printf (" register int ");
5166
5167 printf ("attr_%s = get_attr_%s (insn);\n", attr->name, attr->name);
5168 return 1;
5169 }
5170
5171 fmt = GET_RTX_FORMAT (GET_CODE (p));
5172 ie = GET_RTX_LENGTH (GET_CODE (p));
5173 for (i = 0; i < ie; i++)
5174 {
5175 switch (*fmt++)
5176 {
5177 case 'e':
5178 if (write_expr_attr_cache (XEXP (p, i), attr))
5179 return 1;
5180 break;
5181
5182 case 'E':
5183 je = XVECLEN (p, i);
5184 for (j = 0; j < je; ++j)
5185 if (write_expr_attr_cache (XVECEXP (p, i, j), attr))
5186 return 1;
5187 break;
5188 }
5189 }
5190
5191 return 0;
5192 }
5193
5194 /* Evaluate an expression at top level. A front end to write_test_expr,
5195 in which we cache attribute values and break up excessively large
5196 expressions to cater to older compilers. */
5197
5198 static void
5199 write_toplevel_expr (p)
5200 rtx p;
5201 {
5202 struct attr_desc *attr;
5203 int i;
5204
5205 for (i = 0; i < MAX_ATTRS_INDEX; ++i)
5206 for (attr = attrs[i]; attr ; attr = attr->next)
5207 if (!attr->is_const)
5208 write_expr_attr_cache (p, attr);
5209
5210 printf(" register unsigned long accum = 0;\n\n");
5211
5212 while (GET_CODE (p) == IOR)
5213 {
5214 rtx e;
5215 if (GET_CODE (XEXP (p, 0)) == IOR)
5216 e = XEXP (p, 1), p = XEXP (p, 0);
5217 else
5218 e = XEXP (p, 0), p = XEXP (p, 1);
5219
5220 printf (" accum |= ");
5221 write_test_expr (e, 3);
5222 printf (";\n");
5223 }
5224 printf (" accum |= ");
5225 write_test_expr (p, 3);
5226 printf (";\n");
5227 }
5228 \f
5229 /* Utilities to write names in various forms. */
5230
5231 static void
5232 write_unit_name (prefix, num, suffix)
5233 const char *prefix;
5234 int num;
5235 const char *suffix;
5236 {
5237 struct function_unit *unit;
5238
5239 for (unit = units; unit; unit = unit->next)
5240 if (unit->num == num)
5241 {
5242 printf ("%s%s%s", prefix, unit->name, suffix);
5243 return;
5244 }
5245
5246 printf ("%s<unknown>%s", prefix, suffix);
5247 }
5248
5249 static void
5250 write_attr_valueq (attr, s)
5251 struct attr_desc *attr;
5252 char *s;
5253 {
5254 if (attr->is_numeric)
5255 {
5256 int num = atoi (s);
5257
5258 printf ("%d", num);
5259
5260 /* Make the blockage range values and function units used values easier
5261 to read. */
5262 if (attr->func_units_p)
5263 {
5264 if (num == -1)
5265 printf (" /* units: none */");
5266 else if (num >= 0)
5267 write_unit_name (" /* units: ", num, " */");
5268 else
5269 {
5270 int i;
5271 const char *sep = " /* units: ";
5272 for (i = 0, num = ~num; num; i++, num >>= 1)
5273 if (num & 1)
5274 {
5275 write_unit_name (sep, i, (num == 1) ? " */" : "");
5276 sep = ", ";
5277 }
5278 }
5279 }
5280
5281 else if (attr->blockage_p)
5282 printf (" /* min %d, max %d */", num >> (HOST_BITS_PER_INT / 2),
5283 num & ((1 << (HOST_BITS_PER_INT / 2)) - 1));
5284
5285 else if (num > 9 || num < 0)
5286 printf (" /* 0x%x */", num);
5287 }
5288 else
5289 {
5290 write_upcase (attr->name);
5291 printf ("_");
5292 write_upcase (s);
5293 }
5294 }
5295
5296 static void
5297 write_attr_value (attr, value)
5298 struct attr_desc *attr;
5299 rtx value;
5300 {
5301 int op;
5302
5303 switch (GET_CODE (value))
5304 {
5305 case CONST_STRING:
5306 write_attr_valueq (attr, XSTR (value, 0));
5307 break;
5308
5309 case SYMBOL_REF:
5310 fputs (XSTR (value, 0), stdout);
5311 break;
5312
5313 case ATTR:
5314 {
5315 struct attr_desc *attr2 = find_attr (XSTR (value, 0), 0);
5316 printf ("get_attr_%s (%s)", attr2->name,
5317 (attr2->is_const ? "" : "insn"));
5318 }
5319 break;
5320
5321 case PLUS:
5322 op = '+';
5323 goto do_operator;
5324 case MINUS:
5325 op = '-';
5326 goto do_operator;
5327 case MULT:
5328 op = '*';
5329 goto do_operator;
5330 case DIV:
5331 op = '/';
5332 goto do_operator;
5333 case MOD:
5334 op = '%';
5335 goto do_operator;
5336
5337 do_operator:
5338 write_attr_value (attr, XEXP (value, 0));
5339 putchar (' ');
5340 putchar (op);
5341 putchar (' ');
5342 write_attr_value (attr, XEXP (value, 1));
5343 break;
5344
5345 default:
5346 abort ();
5347 }
5348 }
5349
5350 static void
5351 write_upcase (str)
5352 const char *str;
5353 {
5354 while (*str)
5355 {
5356 /* The argument of TOUPPER should not have side effects. */
5357 putchar (TOUPPER(*str));
5358 str++;
5359 }
5360 }
5361
5362 static void
5363 write_indent (indent)
5364 int indent;
5365 {
5366 for (; indent > 8; indent -= 8)
5367 printf ("\t");
5368
5369 for (; indent; indent--)
5370 printf (" ");
5371 }
5372 \f
5373 /* Write a subroutine that is given an insn that requires a delay slot, a
5374 delay slot ordinal, and a candidate insn. It returns non-zero if the
5375 candidate can be placed in the specified delay slot of the insn.
5376
5377 We can write as many as three subroutines. `eligible_for_delay'
5378 handles normal delay slots, `eligible_for_annul_true' indicates that
5379 the specified insn can be annulled if the branch is true, and likewise
5380 for `eligible_for_annul_false'.
5381
5382 KIND is a string distinguishing these three cases ("delay", "annul_true",
5383 or "annul_false"). */
5384
5385 static void
5386 write_eligible_delay (kind)
5387 const char *kind;
5388 {
5389 struct delay_desc *delay;
5390 int max_slots;
5391 char str[50];
5392 struct attr_desc *attr;
5393 struct attr_value *av, *common_av;
5394 int i;
5395
5396 /* Compute the maximum number of delay slots required. We use the delay
5397 ordinal times this number plus one, plus the slot number as an index into
5398 the appropriate predicate to test. */
5399
5400 for (delay = delays, max_slots = 0; delay; delay = delay->next)
5401 if (XVECLEN (delay->def, 1) / 3 > max_slots)
5402 max_slots = XVECLEN (delay->def, 1) / 3;
5403
5404 /* Write function prelude. */
5405
5406 printf ("int\n");
5407 printf ("eligible_for_%s (delay_insn, slot, candidate_insn, flags)\n",
5408 kind);
5409 printf (" rtx delay_insn;\n");
5410 printf (" int slot;\n");
5411 printf (" rtx candidate_insn;\n");
5412 printf (" int flags ATTRIBUTE_UNUSED;\n");
5413 printf ("{\n");
5414 printf (" rtx insn;\n");
5415 printf ("\n");
5416 printf (" if (slot >= %d)\n", max_slots);
5417 printf (" abort ();\n");
5418 printf ("\n");
5419
5420 /* If more than one delay type, find out which type the delay insn is. */
5421
5422 if (num_delays > 1)
5423 {
5424 attr = find_attr ("*delay_type", 0);
5425 if (! attr) abort ();
5426 common_av = find_most_used (attr);
5427
5428 printf (" insn = delay_insn;\n");
5429 printf (" switch (recog_memoized (insn))\n");
5430 printf (" {\n");
5431
5432 sprintf (str, " * %d;\n break;", max_slots);
5433 for (av = attr->first_value; av; av = av->next)
5434 if (av != common_av)
5435 write_attr_case (attr, av, 1, "slot +=", str, 4, true_rtx);
5436
5437 write_attr_case (attr, common_av, 0, "slot +=", str, 4, true_rtx);
5438 printf (" }\n\n");
5439
5440 /* Ensure matched. Otherwise, shouldn't have been called. */
5441 printf (" if (slot < %d)\n", max_slots);
5442 printf (" abort ();\n\n");
5443 }
5444
5445 /* If just one type of delay slot, write simple switch. */
5446 if (num_delays == 1 && max_slots == 1)
5447 {
5448 printf (" insn = candidate_insn;\n");
5449 printf (" switch (recog_memoized (insn))\n");
5450 printf (" {\n");
5451
5452 attr = find_attr ("*delay_1_0", 0);
5453 if (! attr) abort ();
5454 common_av = find_most_used (attr);
5455
5456 for (av = attr->first_value; av; av = av->next)
5457 if (av != common_av)
5458 write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
5459
5460 write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
5461 printf (" }\n");
5462 }
5463
5464 else
5465 {
5466 /* Write a nested CASE. The first indicates which condition we need to
5467 test, and the inner CASE tests the condition. */
5468 printf (" insn = candidate_insn;\n");
5469 printf (" switch (slot)\n");
5470 printf (" {\n");
5471
5472 for (delay = delays; delay; delay = delay->next)
5473 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
5474 {
5475 printf (" case %d:\n",
5476 (i / 3) + (num_delays == 1 ? 0 : delay->num * max_slots));
5477 printf (" switch (recog_memoized (insn))\n");
5478 printf ("\t{\n");
5479
5480 sprintf (str, "*%s_%d_%d", kind, delay->num, i / 3);
5481 attr = find_attr (str, 0);
5482 if (! attr) abort ();
5483 common_av = find_most_used (attr);
5484
5485 for (av = attr->first_value; av; av = av->next)
5486 if (av != common_av)
5487 write_attr_case (attr, av, 1, "return", ";", 8, true_rtx);
5488
5489 write_attr_case (attr, common_av, 0, "return", ";", 8, true_rtx);
5490 printf (" }\n");
5491 }
5492
5493 printf (" default:\n");
5494 printf (" abort ();\n");
5495 printf (" }\n");
5496 }
5497
5498 printf ("}\n\n");
5499 }
5500 \f
5501 /* Write routines to compute conflict cost for function units. Then write a
5502 table describing the available function units. */
5503
5504 static void
5505 write_function_unit_info ()
5506 {
5507 struct function_unit *unit;
5508 int i;
5509
5510 /* Write out conflict routines for function units. Don't bother writing
5511 one if there is only one issue delay value. */
5512
5513 for (unit = units; unit; unit = unit->next)
5514 {
5515 if (unit->needs_blockage_function)
5516 write_complex_function (unit, "blockage", "block");
5517
5518 /* If the minimum and maximum conflict costs are the same, there
5519 is only one value, so we don't need a function. */
5520 if (! unit->needs_conflict_function)
5521 {
5522 unit->default_cost = make_numeric_value (unit->issue_delay.max);
5523 continue;
5524 }
5525
5526 /* The function first computes the case from the candidate insn. */
5527 unit->default_cost = make_numeric_value (0);
5528 write_complex_function (unit, "conflict_cost", "cost");
5529 }
5530
5531 /* Now that all functions have been written, write the table describing
5532 the function units. The name is included for documentation purposes
5533 only. */
5534
5535 printf ("struct function_unit_desc function_units[] = {\n");
5536
5537 /* Write out the descriptions in numeric order, but don't force that order
5538 on the list. Doing so increases the runtime of genattrtab.c. */
5539 for (i = 0; i < num_units; i++)
5540 {
5541 for (unit = units; unit; unit = unit->next)
5542 if (unit->num == i)
5543 break;
5544
5545 printf (" {\"%s\", %d, %d, %d, %s, %d, %s_unit_ready_cost, ",
5546 unit->name, 1 << unit->num, unit->multiplicity,
5547 unit->simultaneity, XSTR (unit->default_cost, 0),
5548 unit->issue_delay.max, unit->name);
5549
5550 if (unit->needs_conflict_function)
5551 printf ("%s_unit_conflict_cost, ", unit->name);
5552 else
5553 printf ("0, ");
5554
5555 printf ("%d, ", unit->max_blockage);
5556
5557 if (unit->needs_range_function)
5558 printf ("%s_unit_blockage_range, ", unit->name);
5559 else
5560 printf ("0, ");
5561
5562 if (unit->needs_blockage_function)
5563 printf ("%s_unit_blockage", unit->name);
5564 else
5565 printf ("0");
5566
5567 printf ("}, \n");
5568 }
5569
5570 printf ("};\n\n");
5571 }
5572
5573 static void
5574 write_complex_function (unit, name, connection)
5575 struct function_unit *unit;
5576 const char *name, *connection;
5577 {
5578 struct attr_desc *case_attr, *attr;
5579 struct attr_value *av, *common_av;
5580 rtx value;
5581 char *str;
5582 int using_case;
5583 int i;
5584
5585 printf ("static int %s_unit_%s PROTO ((rtx, rtx));\n", unit->name, name);
5586 printf ("static int\n");
5587 printf ("%s_unit_%s (executing_insn, candidate_insn)\n",
5588 unit->name, name);
5589 printf (" rtx executing_insn;\n");
5590 printf (" rtx candidate_insn;\n");
5591 printf ("{\n");
5592 printf (" rtx insn;\n");
5593 printf (" int casenum;\n\n");
5594 printf (" insn = executing_insn;\n");
5595 printf (" switch (recog_memoized (insn))\n");
5596 printf (" {\n");
5597
5598 /* Write the `switch' statement to get the case value. */
5599 str = (char *) alloca (strlen (unit->name) + strlen (name) + strlen (connection) + 10);
5600 sprintf (str, "*%s_cases", unit->name);
5601 case_attr = find_attr (str, 0);
5602 if (! case_attr) abort ();
5603 common_av = find_most_used (case_attr);
5604
5605 for (av = case_attr->first_value; av; av = av->next)
5606 if (av != common_av)
5607 write_attr_case (case_attr, av, 1,
5608 "casenum =", ";", 4, unit->condexp);
5609
5610 write_attr_case (case_attr, common_av, 0,
5611 "casenum =", ";", 4, unit->condexp);
5612 printf (" }\n\n");
5613
5614 /* Now write an outer switch statement on each case. Then write
5615 the tests on the executing function within each. */
5616 printf (" insn = candidate_insn;\n");
5617 printf (" switch (casenum)\n");
5618 printf (" {\n");
5619
5620 for (i = 0; i < unit->num_opclasses; i++)
5621 {
5622 /* Ensure using this case. */
5623 using_case = 0;
5624 for (av = case_attr->first_value; av; av = av->next)
5625 if (av->num_insns
5626 && contained_in_p (make_numeric_value (i), av->value))
5627 using_case = 1;
5628
5629 if (! using_case)
5630 continue;
5631
5632 printf (" case %d:\n", i);
5633 sprintf (str, "*%s_%s_%d", unit->name, connection, i);
5634 attr = find_attr (str, 0);
5635 if (! attr) abort ();
5636
5637 /* If single value, just write it. */
5638 value = find_single_value (attr);
5639 if (value)
5640 write_attr_set (attr, 6, value, "return", ";\n", true_rtx, -2, -2);
5641 else
5642 {
5643 common_av = find_most_used (attr);
5644 printf (" switch (recog_memoized (insn))\n");
5645 printf ("\t{\n");
5646
5647 for (av = attr->first_value; av; av = av->next)
5648 if (av != common_av)
5649 write_attr_case (attr, av, 1,
5650 "return", ";", 8, unit->condexp);
5651
5652 write_attr_case (attr, common_av, 0,
5653 "return", ";", 8, unit->condexp);
5654 printf (" }\n\n");
5655 }
5656 }
5657
5658 /* This default case should not be needed, but gcc's analysis is not
5659 good enough to realize that the default case is not needed for the
5660 second switch statement. */
5661 printf (" default:\n abort ();\n");
5662 printf (" }\n}\n\n");
5663 }
5664 \f
5665 /* This page contains miscellaneous utility routines. */
5666
5667 /* Given a string, return the number of comma-separated elements in it.
5668 Return 0 for the null string. */
5669
5670 static int
5671 n_comma_elts (s)
5672 char *s;
5673 {
5674 int n;
5675
5676 if (*s == '\0')
5677 return 0;
5678
5679 for (n = 1; *s; s++)
5680 if (*s == ',')
5681 n++;
5682
5683 return n;
5684 }
5685
5686 /* Given a pointer to a (char *), return a malloc'ed string containing the
5687 next comma-separated element. Advance the pointer to after the string
5688 scanned, or the end-of-string. Return NULL if at end of string. */
5689
5690 static char *
5691 next_comma_elt (pstr)
5692 char **pstr;
5693 {
5694 char *out_str;
5695 char *p;
5696
5697 if (**pstr == '\0')
5698 return NULL;
5699
5700 /* Find end of string to compute length. */
5701 for (p = *pstr; *p != ',' && *p != '\0'; p++)
5702 ;
5703
5704 out_str = attr_string (*pstr, p - *pstr);
5705 *pstr = p;
5706
5707 if (**pstr == ',')
5708 (*pstr)++;
5709
5710 return out_str;
5711 }
5712
5713 /* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
5714 is non-zero, build a new attribute, if one does not exist. */
5715
5716 static struct attr_desc *
5717 find_attr (name, create)
5718 const char *name;
5719 int create;
5720 {
5721 struct attr_desc *attr;
5722 int index;
5723
5724 /* Before we resort to using `strcmp', see if the string address matches
5725 anywhere. In most cases, it should have been canonicalized to do so. */
5726 if (name == alternative_name)
5727 return NULL;
5728
5729 index = name[0] & (MAX_ATTRS_INDEX - 1);
5730 for (attr = attrs[index]; attr; attr = attr->next)
5731 if (name == attr->name)
5732 return attr;
5733
5734 /* Otherwise, do it the slow way. */
5735 for (attr = attrs[index]; attr; attr = attr->next)
5736 if (name[0] == attr->name[0] && ! strcmp (name, attr->name))
5737 return attr;
5738
5739 if (! create)
5740 return NULL;
5741
5742 attr = (struct attr_desc *) oballoc (sizeof (struct attr_desc));
5743 attr->name = attr_string (name, strlen (name));
5744 attr->first_value = attr->default_val = NULL;
5745 attr->is_numeric = attr->negative_ok = attr->is_const = attr->is_special = 0;
5746 attr->next = attrs[index];
5747 attrs[index] = attr;
5748
5749 return attr;
5750 }
5751
5752 /* Create internal attribute with the given default value. */
5753
5754 static void
5755 make_internal_attr (name, value, special)
5756 const char *name;
5757 rtx value;
5758 int special;
5759 {
5760 struct attr_desc *attr;
5761
5762 attr = find_attr (name, 1);
5763 if (attr->default_val)
5764 abort ();
5765
5766 attr->is_numeric = 1;
5767 attr->is_const = 0;
5768 attr->is_special = (special & 1) != 0;
5769 attr->negative_ok = (special & 2) != 0;
5770 attr->unsigned_p = (special & 4) != 0;
5771 attr->func_units_p = (special & 8) != 0;
5772 attr->blockage_p = (special & 16) != 0;
5773 attr->default_val = get_attr_value (value, attr, -2);
5774 }
5775
5776 /* Find the most used value of an attribute. */
5777
5778 static struct attr_value *
5779 find_most_used (attr)
5780 struct attr_desc *attr;
5781 {
5782 struct attr_value *av;
5783 struct attr_value *most_used;
5784 int nuses;
5785
5786 most_used = NULL;
5787 nuses = -1;
5788
5789 for (av = attr->first_value; av; av = av->next)
5790 if (av->num_insns > nuses)
5791 nuses = av->num_insns, most_used = av;
5792
5793 return most_used;
5794 }
5795
5796 /* If an attribute only has a single value used, return it. Otherwise
5797 return NULL. */
5798
5799 static rtx
5800 find_single_value (attr)
5801 struct attr_desc *attr;
5802 {
5803 struct attr_value *av;
5804 rtx unique_value;
5805
5806 unique_value = NULL;
5807 for (av = attr->first_value; av; av = av->next)
5808 if (av->num_insns)
5809 {
5810 if (unique_value)
5811 return NULL;
5812 else
5813 unique_value = av->value;
5814 }
5815
5816 return unique_value;
5817 }
5818
5819 /* Return (attr_value "n") */
5820
5821 static rtx
5822 make_numeric_value (n)
5823 int n;
5824 {
5825 static rtx int_values[20];
5826 rtx exp;
5827 char *p;
5828
5829 if (n < 0)
5830 abort ();
5831
5832 if (n < 20 && int_values[n])
5833 return int_values[n];
5834
5835 p = attr_printf (MAX_DIGITS, "%d", n);
5836 exp = attr_rtx (CONST_STRING, p);
5837
5838 if (n < 20)
5839 int_values[n] = exp;
5840
5841 return exp;
5842 }
5843 \f
5844 static void
5845 extend_range (range, min, max)
5846 struct range *range;
5847 int min;
5848 int max;
5849 {
5850 if (range->min > min) range->min = min;
5851 if (range->max < max) range->max = max;
5852 }
5853
5854 PTR
5855 xrealloc (old, size)
5856 PTR old;
5857 size_t size;
5858 {
5859 register PTR ptr;
5860 if (old)
5861 ptr = (PTR) realloc (old, size);
5862 else
5863 ptr = (PTR) malloc (size);
5864 if (!ptr)
5865 fatal ("virtual memory exhausted");
5866 return ptr;
5867 }
5868
5869 PTR
5870 xmalloc (size)
5871 size_t size;
5872 {
5873 register PTR val = (PTR) malloc (size);
5874
5875 if (val == 0)
5876 fatal ("virtual memory exhausted");
5877 return val;
5878 }
5879
5880 static rtx
5881 copy_rtx_unchanging (orig)
5882 register rtx orig;
5883 {
5884 #if 0
5885 register rtx copy;
5886 register RTX_CODE code;
5887 #endif
5888
5889 if (RTX_UNCHANGING_P (orig) || MEM_IN_STRUCT_P (orig))
5890 return orig;
5891
5892 MEM_IN_STRUCT_P (orig) = 1;
5893 return orig;
5894
5895 #if 0
5896 code = GET_CODE (orig);
5897 switch (code)
5898 {
5899 case CONST_INT:
5900 case CONST_DOUBLE:
5901 case SYMBOL_REF:
5902 case CODE_LABEL:
5903 return orig;
5904
5905 default:
5906 break;
5907 }
5908
5909 copy = rtx_alloc (code);
5910 PUT_MODE (copy, GET_MODE (orig));
5911 RTX_UNCHANGING_P (copy) = 1;
5912
5913 bcopy ((char *) &XEXP (orig, 0), (char *) &XEXP (copy, 0),
5914 GET_RTX_LENGTH (GET_CODE (copy)) * sizeof (rtx));
5915 return copy;
5916 #endif
5917 }
5918
5919 /* Determine if an insn has a constant number of delay slots, i.e., the
5920 number of delay slots is not a function of the length of the insn. */
5921
5922 static void
5923 write_const_num_delay_slots ()
5924 {
5925 struct attr_desc *attr = find_attr ("*num_delay_slots", 0);
5926 struct attr_value *av;
5927 struct insn_ent *ie;
5928
5929 if (attr)
5930 {
5931 printf ("int\nconst_num_delay_slots (insn)\n");
5932 printf (" rtx insn;\n");
5933 printf ("{\n");
5934 printf (" switch (recog_memoized (insn))\n");
5935 printf (" {\n");
5936
5937 for (av = attr->first_value; av; av = av->next)
5938 {
5939 length_used = 0;
5940 walk_attr_value (av->value);
5941 if (length_used)
5942 {
5943 for (ie = av->first_insn; ie; ie = ie->next)
5944 if (ie->insn_code != -1)
5945 printf (" case %d:\n", ie->insn_code);
5946 printf (" return 0;\n");
5947 }
5948 }
5949
5950 printf (" default:\n");
5951 printf (" return 1;\n");
5952 printf (" }\n}\n\n");
5953 }
5954 }
5955
5956 \f
5957 extern int main PROTO ((int, char **));
5958
5959 int
5960 main (argc, argv)
5961 int argc;
5962 char **argv;
5963 {
5964 rtx desc;
5965 FILE *infile;
5966 register int c;
5967 struct attr_desc *attr;
5968 struct insn_def *id;
5969 rtx tem;
5970 int i;
5971
5972 progname = "genattrtab";
5973
5974 #if defined (RLIMIT_STACK) && defined (HAVE_GETRLIMIT) && defined (HAVE_SETRLIMIT)
5975 /* Get rid of any avoidable limit on stack size. */
5976 {
5977 struct rlimit rlim;
5978
5979 /* Set the stack limit huge so that alloca does not fail. */
5980 getrlimit (RLIMIT_STACK, &rlim);
5981 rlim.rlim_cur = rlim.rlim_max;
5982 setrlimit (RLIMIT_STACK, &rlim);
5983 }
5984 #endif
5985
5986 progname = "genattrtab";
5987 obstack_init (rtl_obstack);
5988 obstack_init (hash_obstack);
5989 obstack_init (temp_obstack);
5990
5991 if (argc <= 1)
5992 fatal ("No input file name.");
5993
5994 infile = fopen (argv[1], "r");
5995 if (infile == 0)
5996 {
5997 perror (argv[1]);
5998 return (FATAL_EXIT_CODE);
5999 }
6000
6001 /* Set up true and false rtx's */
6002 true_rtx = rtx_alloc (CONST_INT);
6003 XWINT (true_rtx, 0) = 1;
6004 false_rtx = rtx_alloc (CONST_INT);
6005 XWINT (false_rtx, 0) = 0;
6006 RTX_UNCHANGING_P (true_rtx) = RTX_UNCHANGING_P (false_rtx) = 1;
6007 RTX_INTEGRATED_P (true_rtx) = RTX_INTEGRATED_P (false_rtx) = 1;
6008
6009 alternative_name = attr_string ("alternative", strlen ("alternative"));
6010
6011 printf ("/* Generated automatically by the program `genattrtab'\n\
6012 from the machine description file `md'. */\n\n");
6013
6014 /* Read the machine description. */
6015
6016 while (1)
6017 {
6018 c = read_skip_spaces (infile);
6019 if (c == EOF)
6020 break;
6021 ungetc (c, infile);
6022
6023 desc = read_rtx (infile);
6024 if (GET_CODE (desc) == DEFINE_INSN
6025 || GET_CODE (desc) == DEFINE_PEEPHOLE
6026 || GET_CODE (desc) == DEFINE_ASM_ATTRIBUTES)
6027 gen_insn (desc);
6028
6029 else if (GET_CODE (desc) == DEFINE_EXPAND)
6030 insn_code_number++, insn_index_number++;
6031
6032 else if (GET_CODE (desc) == DEFINE_SPLIT)
6033 insn_code_number++, insn_index_number++;
6034
6035 else if (GET_CODE (desc) == DEFINE_PEEPHOLE2)
6036 insn_code_number++, insn_index_number++;
6037
6038 else if (GET_CODE (desc) == DEFINE_ATTR)
6039 {
6040 gen_attr (desc);
6041 insn_index_number++;
6042 }
6043
6044 else if (GET_CODE (desc) == DEFINE_DELAY)
6045 {
6046 gen_delay (desc);
6047 insn_index_number++;
6048 }
6049
6050 else if (GET_CODE (desc) == DEFINE_FUNCTION_UNIT)
6051 {
6052 gen_unit (desc);
6053 insn_index_number++;
6054 }
6055 }
6056
6057 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
6058 if (! got_define_asm_attributes)
6059 {
6060 tem = rtx_alloc (DEFINE_ASM_ATTRIBUTES);
6061 XVEC (tem, 0) = rtvec_alloc (0);
6062 gen_insn (tem);
6063 }
6064
6065 /* Expand DEFINE_DELAY information into new attribute. */
6066 if (num_delays)
6067 expand_delays ();
6068
6069 /* Expand DEFINE_FUNCTION_UNIT information into new attributes. */
6070 if (num_units)
6071 expand_units ();
6072
6073 printf ("#include \"config.h\"\n");
6074 printf ("#include \"system.h\"\n");
6075 printf ("#include \"rtl.h\"\n");
6076 printf ("#include \"insn-config.h\"\n");
6077 printf ("#include \"recog.h\"\n");
6078 printf ("#include \"regs.h\"\n");
6079 printf ("#include \"real.h\"\n");
6080 printf ("#include \"output.h\"\n");
6081 printf ("#include \"insn-attr.h\"\n");
6082 printf ("#include \"toplev.h\"\n");
6083 printf ("\n");
6084 printf ("#define operands recog_data.operand\n\n");
6085
6086 /* Make `insn_alternatives'. */
6087 insn_alternatives = (int *) oballoc (insn_code_number * sizeof (int));
6088 for (id = defs; id; id = id->next)
6089 if (id->insn_code >= 0)
6090 insn_alternatives[id->insn_code] = (1 << id->num_alternatives) - 1;
6091
6092 /* Make `insn_n_alternatives'. */
6093 insn_n_alternatives = (int *) oballoc (insn_code_number * sizeof (int));
6094 for (id = defs; id; id = id->next)
6095 if (id->insn_code >= 0)
6096 insn_n_alternatives[id->insn_code] = id->num_alternatives;
6097
6098 /* Prepare to write out attribute subroutines by checking everything stored
6099 away and building the attribute cases. */
6100
6101 check_defs ();
6102 for (i = 0; i < MAX_ATTRS_INDEX; i++)
6103 for (attr = attrs[i]; attr; attr = attr->next)
6104 {
6105 attr->default_val->value
6106 = check_attr_value (attr->default_val->value, attr);
6107 fill_attr (attr);
6108 }
6109
6110 /* Construct extra attributes for `length'. */
6111 make_length_attrs ();
6112
6113 /* Perform any possible optimizations to speed up compilation. */
6114 optimize_attrs ();
6115
6116 /* Now write out all the `gen_attr_...' routines. Do these before the
6117 special routines (specifically before write_function_unit_info), so
6118 that they get defined before they are used. */
6119
6120 for (i = 0; i < MAX_ATTRS_INDEX; i++)
6121 for (attr = attrs[i]; attr; attr = attr->next)
6122 {
6123 if (! attr->is_special && ! attr->is_const)
6124 write_attr_get (attr);
6125 }
6126
6127 /* Write out delay eligibility information, if DEFINE_DELAY present.
6128 (The function to compute the number of delay slots will be written
6129 below.) */
6130 if (num_delays)
6131 {
6132 write_eligible_delay ("delay");
6133 if (have_annul_true)
6134 write_eligible_delay ("annul_true");
6135 if (have_annul_false)
6136 write_eligible_delay ("annul_false");
6137 }
6138
6139 /* Write out information about function units. */
6140 if (num_units)
6141 write_function_unit_info ();
6142
6143 /* Write out constant delay slot info */
6144 write_const_num_delay_slots ();
6145
6146 write_length_unit_log ();
6147
6148 fflush (stdout);
6149 return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
6150 }
6151
6152 /* Define this so we can link with print-rtl.o to get debug_rtx function. */
6153 const char *
6154 get_insn_name (code)
6155 int code ATTRIBUTE_UNUSED;
6156 {
6157 return NULL;
6158 }