Replace insn_foo with insn_data.foo.
[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 struct _global_rtl global_rtl;
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((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 if (ISLOWER(*p))
1358 *p = toupper (*p);
1359
1360 value = attr_rtx (SYMBOL_REF, string);
1361 RTX_UNCHANGING_P (value) = 1;
1362
1363 XVECEXP (condexp, 0, 2 * i) = attr_rtx (EQ, exp, value);
1364
1365 XVECEXP (condexp, 0, 2 * i + 1) = av->value;
1366 }
1367
1368 return condexp;
1369 }
1370 #endif
1371 \f
1372 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1373 expressions by converting them into a COND. This removes cases from this
1374 program. Also, replace an attribute value of "*" with the default attribute
1375 value. */
1376
1377 static rtx
1378 make_canonical (attr, exp)
1379 struct attr_desc *attr;
1380 rtx exp;
1381 {
1382 int i;
1383 rtx newexp;
1384
1385 switch (GET_CODE (exp))
1386 {
1387 case CONST_INT:
1388 exp = make_numeric_value (INTVAL (exp));
1389 break;
1390
1391 case CONST_STRING:
1392 if (! strcmp (XSTR (exp, 0), "*"))
1393 {
1394 if (attr == 0 || attr->default_val == 0)
1395 fatal ("(attr_value \"*\") used in invalid context.");
1396 exp = attr->default_val->value;
1397 }
1398
1399 break;
1400
1401 case SYMBOL_REF:
1402 if (!attr->is_const || RTX_UNCHANGING_P (exp))
1403 break;
1404 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1405 This makes the COND something that won't be considered an arbitrary
1406 expression by walk_attr_value. */
1407 RTX_UNCHANGING_P (exp) = 1;
1408 #if 0
1409 /* ??? Why do we do this? With attribute values { A B C D E }, this
1410 tends to generate (!(x==A) && !(x==B) && !(x==C) && !(x==D)) rather
1411 than (x==E). */
1412 exp = convert_const_symbol_ref (exp, attr);
1413 RTX_UNCHANGING_P (exp) = 1;
1414 exp = check_attr_value (exp, attr);
1415 /* Goto COND case since this is now a COND. Note that while the
1416 new expression is rescanned, all symbol_ref notes are marked as
1417 unchanging. */
1418 goto cond;
1419 #else
1420 exp = check_attr_value (exp, attr);
1421 break;
1422 #endif
1423
1424 case IF_THEN_ELSE:
1425 newexp = rtx_alloc (COND);
1426 XVEC (newexp, 0) = rtvec_alloc (2);
1427 XVECEXP (newexp, 0, 0) = XEXP (exp, 0);
1428 XVECEXP (newexp, 0, 1) = XEXP (exp, 1);
1429
1430 XEXP (newexp, 1) = XEXP (exp, 2);
1431
1432 exp = newexp;
1433 /* Fall through to COND case since this is now a COND. */
1434
1435 case COND:
1436 {
1437 int allsame = 1;
1438 rtx defval;
1439
1440 /* First, check for degenerate COND. */
1441 if (XVECLEN (exp, 0) == 0)
1442 return make_canonical (attr, XEXP (exp, 1));
1443 defval = XEXP (exp, 1) = make_canonical (attr, XEXP (exp, 1));
1444
1445 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1446 {
1447 XVECEXP (exp, 0, i) = copy_boolean (XVECEXP (exp, 0, i));
1448 XVECEXP (exp, 0, i + 1)
1449 = make_canonical (attr, XVECEXP (exp, 0, i + 1));
1450 if (! rtx_equal_p (XVECEXP (exp, 0, i + 1), defval))
1451 allsame = 0;
1452 }
1453 if (allsame)
1454 return defval;
1455 }
1456 break;
1457
1458 default:
1459 break;
1460 }
1461
1462 return exp;
1463 }
1464
1465 static rtx
1466 copy_boolean (exp)
1467 rtx exp;
1468 {
1469 if (GET_CODE (exp) == AND || GET_CODE (exp) == IOR)
1470 return attr_rtx (GET_CODE (exp), copy_boolean (XEXP (exp, 0)),
1471 copy_boolean (XEXP (exp, 1)));
1472 return exp;
1473 }
1474 \f
1475 /* Given a value and an attribute description, return a `struct attr_value *'
1476 that represents that value. This is either an existing structure, if the
1477 value has been previously encountered, or a newly-created structure.
1478
1479 `insn_code' is the code of an insn whose attribute has the specified
1480 value (-2 if not processing an insn). We ensure that all insns for
1481 a given value have the same number of alternatives if the value checks
1482 alternatives. */
1483
1484 static struct attr_value *
1485 get_attr_value (value, attr, insn_code)
1486 rtx value;
1487 struct attr_desc *attr;
1488 int insn_code;
1489 {
1490 struct attr_value *av;
1491 int num_alt = 0;
1492
1493 value = make_canonical (attr, value);
1494 if (compares_alternatives_p (value))
1495 {
1496 if (insn_code < 0 || insn_alternatives == NULL)
1497 fatal ("(eq_attr \"alternatives\" ...) used in non-insn context");
1498 else
1499 num_alt = insn_alternatives[insn_code];
1500 }
1501
1502 for (av = attr->first_value; av; av = av->next)
1503 if (rtx_equal_p (value, av->value)
1504 && (num_alt == 0 || av->first_insn == NULL
1505 || insn_alternatives[av->first_insn->insn_code]))
1506 return av;
1507
1508 av = (struct attr_value *) oballoc (sizeof (struct attr_value));
1509 av->value = value;
1510 av->next = attr->first_value;
1511 attr->first_value = av;
1512 av->first_insn = NULL;
1513 av->num_insns = 0;
1514 av->has_asm_insn = 0;
1515
1516 return av;
1517 }
1518 \f
1519 /* After all DEFINE_DELAYs have been read in, create internal attributes
1520 to generate the required routines.
1521
1522 First, we compute the number of delay slots for each insn (as a COND of
1523 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1524 delay type is specified, we compute a similar function giving the
1525 DEFINE_DELAY ordinal for each insn.
1526
1527 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1528 tells whether a given insn can be in that delay slot.
1529
1530 Normal attribute filling and optimization expands these to contain the
1531 information needed to handle delay slots. */
1532
1533 static void
1534 expand_delays ()
1535 {
1536 struct delay_desc *delay;
1537 rtx condexp;
1538 rtx newexp;
1539 int i;
1540 char *p;
1541
1542 /* First, generate data for `num_delay_slots' function. */
1543
1544 condexp = rtx_alloc (COND);
1545 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1546 XEXP (condexp, 1) = make_numeric_value (0);
1547
1548 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1549 {
1550 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1551 XVECEXP (condexp, 0, i + 1)
1552 = make_numeric_value (XVECLEN (delay->def, 1) / 3);
1553 }
1554
1555 make_internal_attr ("*num_delay_slots", condexp, 0);
1556
1557 /* If more than one delay type, do the same for computing the delay type. */
1558 if (num_delays > 1)
1559 {
1560 condexp = rtx_alloc (COND);
1561 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1562 XEXP (condexp, 1) = make_numeric_value (0);
1563
1564 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1565 {
1566 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1567 XVECEXP (condexp, 0, i + 1) = make_numeric_value (delay->num);
1568 }
1569
1570 make_internal_attr ("*delay_type", condexp, 1);
1571 }
1572
1573 /* For each delay possibility and delay slot, compute an eligibility
1574 attribute for non-annulled insns and for each type of annulled (annul
1575 if true and annul if false). */
1576 for (delay = delays; delay; delay = delay->next)
1577 {
1578 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
1579 {
1580 condexp = XVECEXP (delay->def, 1, i);
1581 if (condexp == 0) condexp = false_rtx;
1582 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1583 make_numeric_value (1), make_numeric_value (0));
1584
1585 p = attr_printf (sizeof ("*delay__") + MAX_DIGITS*2, "*delay_%d_%d",
1586 delay->num, i / 3);
1587 make_internal_attr (p, newexp, 1);
1588
1589 if (have_annul_true)
1590 {
1591 condexp = XVECEXP (delay->def, 1, i + 1);
1592 if (condexp == 0) condexp = false_rtx;
1593 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1594 make_numeric_value (1),
1595 make_numeric_value (0));
1596 p = attr_printf (sizeof ("*annul_true__") + MAX_DIGITS*2,
1597 "*annul_true_%d_%d", delay->num, i / 3);
1598 make_internal_attr (p, newexp, 1);
1599 }
1600
1601 if (have_annul_false)
1602 {
1603 condexp = XVECEXP (delay->def, 1, i + 2);
1604 if (condexp == 0) condexp = false_rtx;
1605 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1606 make_numeric_value (1),
1607 make_numeric_value (0));
1608 p = attr_printf (sizeof ("*annul_false__") + MAX_DIGITS*2,
1609 "*annul_false_%d_%d", delay->num, i / 3);
1610 make_internal_attr (p, newexp, 1);
1611 }
1612 }
1613 }
1614 }
1615 \f
1616 /* This function is given a left and right side expression and an operator.
1617 Each side is a conditional expression, each alternative of which has a
1618 numerical value. The function returns another conditional expression
1619 which, for every possible set of condition values, returns a value that is
1620 the operator applied to the values of the two sides.
1621
1622 Since this is called early, it must also support IF_THEN_ELSE. */
1623
1624 static rtx
1625 operate_exp (op, left, right)
1626 enum operator op;
1627 rtx left, right;
1628 {
1629 int left_value, right_value;
1630 rtx newexp;
1631 int i;
1632
1633 /* If left is a string, apply operator to it and the right side. */
1634 if (GET_CODE (left) == CONST_STRING)
1635 {
1636 /* If right is also a string, just perform the operation. */
1637 if (GET_CODE (right) == CONST_STRING)
1638 {
1639 left_value = atoi (XSTR (left, 0));
1640 right_value = atoi (XSTR (right, 0));
1641 switch (op)
1642 {
1643 case PLUS_OP:
1644 i = left_value + right_value;
1645 break;
1646
1647 case MINUS_OP:
1648 i = left_value - right_value;
1649 break;
1650
1651 case POS_MINUS_OP: /* The positive part of LEFT - RIGHT. */
1652 if (left_value > right_value)
1653 i = left_value - right_value;
1654 else
1655 i = 0;
1656 break;
1657
1658 case OR_OP:
1659 case ORX_OP:
1660 i = left_value | right_value;
1661 break;
1662
1663 case EQ_OP:
1664 i = left_value == right_value;
1665 break;
1666
1667 case RANGE_OP:
1668 i = (left_value << (HOST_BITS_PER_INT / 2)) | right_value;
1669 break;
1670
1671 case MAX_OP:
1672 if (left_value > right_value)
1673 i = left_value;
1674 else
1675 i = right_value;
1676 break;
1677
1678 case MIN_OP:
1679 if (left_value < right_value)
1680 i = left_value;
1681 else
1682 i = right_value;
1683 break;
1684
1685 default:
1686 abort ();
1687 }
1688
1689 if (i == left_value)
1690 return left;
1691 if (i == right_value)
1692 return right;
1693 return make_numeric_value (i);
1694 }
1695 else if (GET_CODE (right) == IF_THEN_ELSE)
1696 {
1697 /* Apply recursively to all values within. */
1698 rtx newleft = operate_exp (op, left, XEXP (right, 1));
1699 rtx newright = operate_exp (op, left, XEXP (right, 2));
1700 if (rtx_equal_p (newleft, newright))
1701 return newleft;
1702 return attr_rtx (IF_THEN_ELSE, XEXP (right, 0), newleft, newright);
1703 }
1704 else if (GET_CODE (right) == COND)
1705 {
1706 int allsame = 1;
1707 rtx defval;
1708
1709 newexp = rtx_alloc (COND);
1710 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (right, 0));
1711 defval = XEXP (newexp, 1) = operate_exp (op, left, XEXP (right, 1));
1712
1713 for (i = 0; i < XVECLEN (right, 0); i += 2)
1714 {
1715 XVECEXP (newexp, 0, i) = XVECEXP (right, 0, i);
1716 XVECEXP (newexp, 0, i + 1)
1717 = operate_exp (op, left, XVECEXP (right, 0, i + 1));
1718 if (! rtx_equal_p (XVECEXP (newexp, 0, i + 1),
1719 defval))
1720 allsame = 0;
1721 }
1722
1723 /* If the resulting cond is trivial (all alternatives
1724 give the same value), optimize it away. */
1725 if (allsame)
1726 {
1727 if (!ggc_p)
1728 obstack_free (rtl_obstack, newexp);
1729 return operate_exp (op, left, XEXP (right, 1));
1730 }
1731
1732 /* If the result is the same as the RIGHT operand,
1733 just use that. */
1734 if (rtx_equal_p (newexp, right))
1735 {
1736 if (!ggc_p)
1737 obstack_free (rtl_obstack, newexp);
1738 return right;
1739 }
1740
1741 return newexp;
1742 }
1743 else
1744 fatal ("Badly formed attribute value");
1745 }
1746
1747 /* A hack to prevent expand_units from completely blowing up: ORX_OP does
1748 not associate through IF_THEN_ELSE. */
1749 else if (op == ORX_OP && GET_CODE (right) == IF_THEN_ELSE)
1750 {
1751 return attr_rtx (IOR, left, right);
1752 }
1753
1754 /* Otherwise, do recursion the other way. */
1755 else if (GET_CODE (left) == IF_THEN_ELSE)
1756 {
1757 rtx newleft = operate_exp (op, XEXP (left, 1), right);
1758 rtx newright = operate_exp (op, XEXP (left, 2), right);
1759 if (rtx_equal_p (newleft, newright))
1760 return newleft;
1761 return attr_rtx (IF_THEN_ELSE, XEXP (left, 0), newleft, newright);
1762 }
1763 else if (GET_CODE (left) == COND)
1764 {
1765 int allsame = 1;
1766 rtx defval;
1767
1768 newexp = rtx_alloc (COND);
1769 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (left, 0));
1770 defval = XEXP (newexp, 1) = operate_exp (op, XEXP (left, 1), right);
1771
1772 for (i = 0; i < XVECLEN (left, 0); i += 2)
1773 {
1774 XVECEXP (newexp, 0, i) = XVECEXP (left, 0, i);
1775 XVECEXP (newexp, 0, i + 1)
1776 = operate_exp (op, XVECEXP (left, 0, i + 1), right);
1777 if (! rtx_equal_p (XVECEXP (newexp, 0, i + 1),
1778 defval))
1779 allsame = 0;
1780 }
1781
1782 /* If the cond is trivial (all alternatives give the same value),
1783 optimize it away. */
1784 if (allsame)
1785 {
1786 if (!ggc_p)
1787 obstack_free (rtl_obstack, newexp);
1788 return operate_exp (op, XEXP (left, 1), right);
1789 }
1790
1791 /* If the result is the same as the LEFT operand,
1792 just use that. */
1793 if (rtx_equal_p (newexp, left))
1794 {
1795 if (!ggc_p)
1796 obstack_free (rtl_obstack, newexp);
1797 return left;
1798 }
1799
1800 return newexp;
1801 }
1802
1803 else
1804 fatal ("Badly formed attribute value.");
1805 /* NOTREACHED */
1806 return NULL;
1807 }
1808 \f
1809 /* Once all attributes and DEFINE_FUNCTION_UNITs have been read, we
1810 construct a number of attributes.
1811
1812 The first produces a function `function_units_used' which is given an
1813 insn and produces an encoding showing which function units are required
1814 for the execution of that insn. If the value is non-negative, the insn
1815 uses that unit; otherwise, the value is a one's compliment mask of units
1816 used.
1817
1818 The second produces a function `result_ready_cost' which is used to
1819 determine the time that the result of an insn will be ready and hence
1820 a worst-case schedule.
1821
1822 Both of these produce quite complex expressions which are then set as the
1823 default value of internal attributes. Normal attribute simplification
1824 should produce reasonable expressions.
1825
1826 For each unit, a `<name>_unit_ready_cost' function will take an
1827 insn and give the delay until that unit will be ready with the result
1828 and a `<name>_unit_conflict_cost' function is given an insn already
1829 executing on the unit and a candidate to execute and will give the
1830 cost from the time the executing insn started until the candidate
1831 can start (ignore limitations on the number of simultaneous insns).
1832
1833 For each unit, a `<name>_unit_blockage' function is given an insn
1834 already executing on the unit and a candidate to execute and will
1835 give the delay incurred due to function unit conflicts. The range of
1836 blockage cost values for a given executing insn is given by the
1837 `<name>_unit_blockage_range' function. These values are encoded in
1838 an int where the upper half gives the minimum value and the lower
1839 half gives the maximum value. */
1840
1841 static void
1842 expand_units ()
1843 {
1844 struct function_unit *unit, **unit_num;
1845 struct function_unit_op *op, **op_array, ***unit_ops;
1846 rtx unitsmask;
1847 rtx readycost;
1848 rtx newexp;
1849 const char *str;
1850 int i, j, u, num, nvalues;
1851
1852 /* Rebuild the condition for the unit to share the RTL expressions.
1853 Sharing is required by simplify_by_exploding. Build the issue delay
1854 expressions. Validate the expressions we were given for the conditions
1855 and conflict vector. Then make attributes for use in the conflict
1856 function. */
1857
1858 for (unit = units; unit; unit = unit->next)
1859 {
1860 unit->condexp = check_attr_test (unit->condexp, 0);
1861
1862 for (op = unit->ops; op; op = op->next)
1863 {
1864 rtx issue_delay = make_numeric_value (op->issue_delay);
1865 rtx issue_exp = issue_delay;
1866
1867 /* Build, validate, and simplify the issue delay expression. */
1868 if (op->conflict_exp != true_rtx)
1869 issue_exp = attr_rtx (IF_THEN_ELSE, op->conflict_exp,
1870 issue_exp, make_numeric_value (0));
1871 issue_exp = check_attr_value (make_canonical (NULL_ATTR,
1872 issue_exp),
1873 NULL_ATTR);
1874 issue_exp = simplify_knowing (issue_exp, unit->condexp);
1875 op->issue_exp = issue_exp;
1876
1877 /* Make an attribute for use in the conflict function if needed. */
1878 unit->needs_conflict_function = (unit->issue_delay.min
1879 != unit->issue_delay.max);
1880 if (unit->needs_conflict_function)
1881 {
1882 str = attr_printf (strlen (unit->name) + sizeof ("*_cost_") + MAX_DIGITS,
1883 "*%s_cost_%d", unit->name, op->num);
1884 make_internal_attr (str, issue_exp, 1);
1885 }
1886
1887 /* Validate the condition. */
1888 op->condexp = check_attr_test (op->condexp, 0);
1889 }
1890 }
1891
1892 /* Compute the mask of function units used. Initially, the unitsmask is
1893 zero. Set up a conditional to compute each unit's contribution. */
1894 unitsmask = make_numeric_value (0);
1895 newexp = rtx_alloc (IF_THEN_ELSE);
1896 XEXP (newexp, 2) = make_numeric_value (0);
1897
1898 /* If we have just a few units, we may be all right expanding the whole
1899 thing. But the expansion is 2**N in space on the number of opclasses,
1900 so we can't do this for very long -- Alpha and MIPS in particular have
1901 problems with this. So in that situation, we fall back on an alternate
1902 implementation method. */
1903 #define NUM_UNITOP_CUTOFF 20
1904
1905 if (num_unit_opclasses < NUM_UNITOP_CUTOFF)
1906 {
1907 /* Merge each function unit into the unit mask attributes. */
1908 for (unit = units; unit; unit = unit->next)
1909 {
1910 XEXP (newexp, 0) = unit->condexp;
1911 XEXP (newexp, 1) = make_numeric_value (1 << unit->num);
1912 unitsmask = operate_exp (OR_OP, unitsmask, newexp);
1913 }
1914 }
1915 else
1916 {
1917 /* Merge each function unit into the unit mask attributes. */
1918 for (unit = units; unit; unit = unit->next)
1919 {
1920 XEXP (newexp, 0) = unit->condexp;
1921 XEXP (newexp, 1) = make_numeric_value (1 << unit->num);
1922 unitsmask = operate_exp (ORX_OP, unitsmask, attr_copy_rtx (newexp));
1923 }
1924 }
1925
1926 /* Simplify the unit mask expression, encode it, and make an attribute
1927 for the function_units_used function. */
1928 unitsmask = simplify_by_exploding (unitsmask);
1929
1930 if (num_unit_opclasses < NUM_UNITOP_CUTOFF)
1931 unitsmask = encode_units_mask (unitsmask);
1932 else
1933 {
1934 /* We can no longer encode unitsmask at compile time, so emit code to
1935 calculate it at runtime. Rather, put a marker for where we'd do
1936 the code, and actually output it in write_attr_get(). */
1937 unitsmask = attr_rtx (FFS, unitsmask);
1938 }
1939
1940 make_internal_attr ("*function_units_used", unitsmask, 10);
1941
1942 /* Create an array of ops for each unit. Add an extra unit for the
1943 result_ready_cost function that has the ops of all other units. */
1944 unit_ops = (struct function_unit_op ***)
1945 alloca ((num_units + 1) * sizeof (struct function_unit_op **));
1946 unit_num = (struct function_unit **)
1947 alloca ((num_units + 1) * sizeof (struct function_unit *));
1948
1949 unit_num[num_units] = unit = (struct function_unit *)
1950 alloca (sizeof (struct function_unit));
1951 unit->num = num_units;
1952 unit->num_opclasses = 0;
1953
1954 for (unit = units; unit; unit = unit->next)
1955 {
1956 unit_num[num_units]->num_opclasses += unit->num_opclasses;
1957 unit_num[unit->num] = unit;
1958 unit_ops[unit->num] = op_array = (struct function_unit_op **)
1959 alloca (unit->num_opclasses * sizeof (struct function_unit_op *));
1960
1961 for (op = unit->ops; op; op = op->next)
1962 op_array[op->num] = op;
1963 }
1964
1965 /* Compose the array of ops for the extra unit. */
1966 unit_ops[num_units] = op_array = (struct function_unit_op **)
1967 alloca (unit_num[num_units]->num_opclasses
1968 * sizeof (struct function_unit_op *));
1969
1970 for (unit = units, i = 0; unit; i += unit->num_opclasses, unit = unit->next)
1971 bcopy ((char *) unit_ops[unit->num], (char *) &op_array[i],
1972 unit->num_opclasses * sizeof (struct function_unit_op *));
1973
1974 /* Compute the ready cost function for each unit by computing the
1975 condition for each non-default value. */
1976 for (u = 0; u <= num_units; u++)
1977 {
1978 rtx orexp;
1979 int value;
1980
1981 unit = unit_num[u];
1982 op_array = unit_ops[unit->num];
1983 num = unit->num_opclasses;
1984
1985 /* Sort the array of ops into increasing ready cost order. */
1986 for (i = 0; i < num; i++)
1987 for (j = num - 1; j > i; j--)
1988 if (op_array[j-1]->ready < op_array[j]->ready)
1989 {
1990 op = op_array[j];
1991 op_array[j] = op_array[j-1];
1992 op_array[j-1] = op;
1993 }
1994
1995 /* Determine how many distinct non-default ready cost values there
1996 are. We use a default ready cost value of 1. */
1997 nvalues = 0; value = 1;
1998 for (i = num - 1; i >= 0; i--)
1999 if (op_array[i]->ready > value)
2000 {
2001 value = op_array[i]->ready;
2002 nvalues++;
2003 }
2004
2005 if (nvalues == 0)
2006 readycost = make_numeric_value (1);
2007 else
2008 {
2009 /* Construct the ready cost expression as a COND of each value from
2010 the largest to the smallest. */
2011 readycost = rtx_alloc (COND);
2012 XVEC (readycost, 0) = rtvec_alloc (nvalues * 2);
2013 XEXP (readycost, 1) = make_numeric_value (1);
2014
2015 nvalues = 0; orexp = false_rtx; value = op_array[0]->ready;
2016 for (i = 0; i < num; i++)
2017 {
2018 op = op_array[i];
2019 if (op->ready <= 1)
2020 break;
2021 else if (op->ready == value)
2022 orexp = insert_right_side (IOR, orexp, op->condexp, -2, -2);
2023 else
2024 {
2025 XVECEXP (readycost, 0, nvalues * 2) = orexp;
2026 XVECEXP (readycost, 0, nvalues * 2 + 1)
2027 = make_numeric_value (value);
2028 nvalues++;
2029 value = op->ready;
2030 orexp = op->condexp;
2031 }
2032 }
2033 XVECEXP (readycost, 0, nvalues * 2) = orexp;
2034 XVECEXP (readycost, 0, nvalues * 2 + 1) = make_numeric_value (value);
2035 }
2036
2037 if (u < num_units)
2038 {
2039 rtx max_blockage = 0, min_blockage = 0;
2040
2041 /* Simplify the readycost expression by only considering insns
2042 that use the unit. */
2043 readycost = simplify_knowing (readycost, unit->condexp);
2044
2045 /* Determine the blockage cost the executing insn (E) given
2046 the candidate insn (C). This is the maximum of the issue
2047 delay, the pipeline delay, and the simultaneity constraint.
2048 Each function_unit_op represents the characteristics of the
2049 candidate insn, so in the expressions below, C is a known
2050 term and E is an unknown term.
2051
2052 We compute the blockage cost for each E for every possible C.
2053 Thus OP represents E, and READYCOST is a list of values for
2054 every possible C.
2055
2056 The issue delay function for C is op->issue_exp and is used to
2057 write the `<name>_unit_conflict_cost' function. Symbolicly
2058 this is "ISSUE-DELAY (E,C)".
2059
2060 The pipeline delay results form the FIFO constraint on the
2061 function unit and is "READY-COST (E) + 1 - READY-COST (C)".
2062
2063 The simultaneity constraint is based on how long it takes to
2064 fill the unit given the minimum issue delay. FILL-TIME is the
2065 constant "MIN (ISSUE-DELAY (*,*)) * (SIMULTANEITY - 1)", and
2066 the simultaneity constraint is "READY-COST (E) - FILL-TIME"
2067 if SIMULTANEITY is non-zero and zero otherwise.
2068
2069 Thus, BLOCKAGE (E,C) when SIMULTANEITY is zero is
2070
2071 MAX (ISSUE-DELAY (E,C),
2072 READY-COST (E) - (READY-COST (C) - 1))
2073
2074 and otherwise
2075
2076 MAX (ISSUE-DELAY (E,C),
2077 READY-COST (E) - (READY-COST (C) - 1),
2078 READY-COST (E) - FILL-TIME)
2079
2080 The `<name>_unit_blockage' function is computed by determining
2081 this value for each candidate insn. As these values are
2082 computed, we also compute the upper and lower bounds for
2083 BLOCKAGE (E,*). These are combined to form the function
2084 `<name>_unit_blockage_range'. Finally, the maximum blockage
2085 cost, MAX (BLOCKAGE (*,*)), is computed. */
2086
2087 for (op = unit->ops; op; op = op->next)
2088 {
2089 rtx blockage = op->issue_exp;
2090 blockage = simplify_knowing (blockage, unit->condexp);
2091
2092 /* Add this op's contribution to MAX (BLOCKAGE (E,*)) and
2093 MIN (BLOCKAGE (E,*)). */
2094 if (max_blockage == 0)
2095 max_blockage = min_blockage = blockage;
2096 else
2097 {
2098 max_blockage
2099 = simplify_knowing (operate_exp (MAX_OP, max_blockage,
2100 blockage),
2101 unit->condexp);
2102 min_blockage
2103 = simplify_knowing (operate_exp (MIN_OP, min_blockage,
2104 blockage),
2105 unit->condexp);
2106 }
2107
2108 /* Make an attribute for use in the blockage function. */
2109 str = attr_printf (strlen (unit->name) + sizeof ("*_block_") + MAX_DIGITS,
2110 "*%s_block_%d", unit->name, op->num);
2111 make_internal_attr (str, blockage, 1);
2112 }
2113
2114 /* Record MAX (BLOCKAGE (*,*)). */
2115 {
2116 int unknown;
2117 unit->max_blockage = max_attr_value (max_blockage, &unknown);
2118 }
2119
2120 /* See if the upper and lower bounds of BLOCKAGE (E,*) are the
2121 same. If so, the blockage function carries no additional
2122 information and is not written. */
2123 newexp = operate_exp (EQ_OP, max_blockage, min_blockage);
2124 newexp = simplify_knowing (newexp, unit->condexp);
2125 unit->needs_blockage_function
2126 = (GET_CODE (newexp) != CONST_STRING
2127 || atoi (XSTR (newexp, 0)) != 1);
2128
2129 /* If the all values of BLOCKAGE (E,C) have the same value,
2130 neither blockage function is written. */
2131 unit->needs_range_function
2132 = (unit->needs_blockage_function
2133 || GET_CODE (max_blockage) != CONST_STRING);
2134
2135 if (unit->needs_range_function)
2136 {
2137 /* Compute the blockage range function and make an attribute
2138 for writing its value. */
2139 newexp = operate_exp (RANGE_OP, min_blockage, max_blockage);
2140 newexp = simplify_knowing (newexp, unit->condexp);
2141
2142 str = attr_printf (strlen (unit->name) + sizeof ("*_unit_blockage_range"),
2143 "*%s_unit_blockage_range", unit->name);
2144 make_internal_attr (str, newexp, 20);
2145 }
2146
2147 str = attr_printf (strlen (unit->name) + sizeof ("*_unit_ready_cost"),
2148 "*%s_unit_ready_cost", unit->name);
2149 }
2150 else
2151 str = "*result_ready_cost";
2152
2153 /* Make an attribute for the ready_cost function. Simplifying
2154 further with simplify_by_exploding doesn't win. */
2155 make_internal_attr (str, readycost, 0);
2156 }
2157
2158 /* For each unit that requires a conflict cost function, make an attribute
2159 that maps insns to the operation number. */
2160 for (unit = units; unit; unit = unit->next)
2161 {
2162 rtx caseexp;
2163
2164 if (! unit->needs_conflict_function
2165 && ! unit->needs_blockage_function)
2166 continue;
2167
2168 caseexp = rtx_alloc (COND);
2169 XVEC (caseexp, 0) = rtvec_alloc ((unit->num_opclasses - 1) * 2);
2170
2171 for (op = unit->ops; op; op = op->next)
2172 {
2173 /* Make our adjustment to the COND being computed. If we are the
2174 last operation class, place our values into the default of the
2175 COND. */
2176 if (op->num == unit->num_opclasses - 1)
2177 {
2178 XEXP (caseexp, 1) = make_numeric_value (op->num);
2179 }
2180 else
2181 {
2182 XVECEXP (caseexp, 0, op->num * 2) = op->condexp;
2183 XVECEXP (caseexp, 0, op->num * 2 + 1)
2184 = make_numeric_value (op->num);
2185 }
2186 }
2187
2188 /* Simplifying caseexp with simplify_by_exploding doesn't win. */
2189 str = attr_printf (strlen (unit->name) + sizeof ("*_cases"),
2190 "*%s_cases", unit->name);
2191 make_internal_attr (str, caseexp, 1);
2192 }
2193 }
2194
2195 /* Simplify EXP given KNOWN_TRUE. */
2196
2197 static rtx
2198 simplify_knowing (exp, known_true)
2199 rtx exp, known_true;
2200 {
2201 if (GET_CODE (exp) != CONST_STRING)
2202 {
2203 int unknown = 0, max;
2204 max = max_attr_value (exp, &unknown);
2205 if (! unknown)
2206 {
2207 exp = attr_rtx (IF_THEN_ELSE, known_true, exp,
2208 make_numeric_value (max));
2209 exp = simplify_by_exploding (exp);
2210 }
2211 }
2212 return exp;
2213 }
2214
2215 /* Translate the CONST_STRING expressions in X to change the encoding of
2216 value. On input, the value is a bitmask with a one bit for each unit
2217 used; on output, the value is the unit number (zero based) if one
2218 and only one unit is used or the one's compliment of the bitmask. */
2219
2220 static rtx
2221 encode_units_mask (x)
2222 rtx x;
2223 {
2224 register int i;
2225 register int j;
2226 register enum rtx_code code;
2227 register const char *fmt;
2228
2229 code = GET_CODE (x);
2230
2231 switch (code)
2232 {
2233 case CONST_STRING:
2234 i = atoi (XSTR (x, 0));
2235 if (i < 0)
2236 abort (); /* The sign bit encodes a one's compliment mask. */
2237 else if (i != 0 && i == (i & -i))
2238 /* Only one bit is set, so yield that unit number. */
2239 for (j = 0; (i >>= 1) != 0; j++)
2240 ;
2241 else
2242 j = ~i;
2243 return attr_rtx (CONST_STRING, attr_printf (MAX_DIGITS, "%d", j));
2244
2245 case REG:
2246 case QUEUED:
2247 case CONST_INT:
2248 case CONST_DOUBLE:
2249 case SYMBOL_REF:
2250 case CODE_LABEL:
2251 case PC:
2252 case CC0:
2253 case EQ_ATTR:
2254 return x;
2255
2256 default:
2257 break;
2258 }
2259
2260 /* Compare the elements. If any pair of corresponding elements
2261 fail to match, return 0 for the whole things. */
2262
2263 fmt = GET_RTX_FORMAT (code);
2264 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
2265 {
2266 switch (fmt[i])
2267 {
2268 case 'V':
2269 case 'E':
2270 for (j = 0; j < XVECLEN (x, i); j++)
2271 XVECEXP (x, i, j) = encode_units_mask (XVECEXP (x, i, j));
2272 break;
2273
2274 case 'e':
2275 XEXP (x, i) = encode_units_mask (XEXP (x, i));
2276 break;
2277 }
2278 }
2279 return x;
2280 }
2281 \f
2282 /* Once all attributes and insns have been read and checked, we construct for
2283 each attribute value a list of all the insns that have that value for
2284 the attribute. */
2285
2286 static void
2287 fill_attr (attr)
2288 struct attr_desc *attr;
2289 {
2290 struct attr_value *av;
2291 struct insn_ent *ie;
2292 struct insn_def *id;
2293 int i;
2294 rtx value;
2295
2296 /* Don't fill constant attributes. The value is independent of
2297 any particular insn. */
2298 if (attr->is_const)
2299 return;
2300
2301 for (id = defs; id; id = id->next)
2302 {
2303 /* If no value is specified for this insn for this attribute, use the
2304 default. */
2305 value = NULL;
2306 if (XVEC (id->def, id->vec_idx))
2307 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
2308 if (! strcmp (XSTR (XEXP (XVECEXP (id->def, id->vec_idx, i), 0), 0),
2309 attr->name))
2310 value = XEXP (XVECEXP (id->def, id->vec_idx, i), 1);
2311
2312 if (value == NULL)
2313 av = attr->default_val;
2314 else
2315 av = get_attr_value (value, attr, id->insn_code);
2316
2317 ie = (struct insn_ent *) oballoc (sizeof (struct insn_ent));
2318 ie->insn_code = id->insn_code;
2319 ie->insn_index = id->insn_code;
2320 insert_insn_ent (av, ie);
2321 }
2322 }
2323 \f
2324 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
2325 test that checks relative positions of insns (uses MATCH_DUP or PC).
2326 If so, replace it with what is obtained by passing the expression to
2327 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
2328 recursively on each value (including the default value). Otherwise,
2329 return the value returned by NO_ADDRESS_FN applied to EXP. */
2330
2331 static rtx
2332 substitute_address (exp, no_address_fn, address_fn)
2333 rtx exp;
2334 rtx (*no_address_fn) PROTO ((rtx));
2335 rtx (*address_fn) PROTO ((rtx));
2336 {
2337 int i;
2338 rtx newexp;
2339
2340 if (GET_CODE (exp) == COND)
2341 {
2342 /* See if any tests use addresses. */
2343 address_used = 0;
2344 for (i = 0; i < XVECLEN (exp, 0); i += 2)
2345 walk_attr_value (XVECEXP (exp, 0, i));
2346
2347 if (address_used)
2348 return (*address_fn) (exp);
2349
2350 /* Make a new copy of this COND, replacing each element. */
2351 newexp = rtx_alloc (COND);
2352 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
2353 for (i = 0; i < XVECLEN (exp, 0); i += 2)
2354 {
2355 XVECEXP (newexp, 0, i) = XVECEXP (exp, 0, i);
2356 XVECEXP (newexp, 0, i + 1)
2357 = substitute_address (XVECEXP (exp, 0, i + 1),
2358 no_address_fn, address_fn);
2359 }
2360
2361 XEXP (newexp, 1) = substitute_address (XEXP (exp, 1),
2362 no_address_fn, address_fn);
2363
2364 return newexp;
2365 }
2366
2367 else if (GET_CODE (exp) == IF_THEN_ELSE)
2368 {
2369 address_used = 0;
2370 walk_attr_value (XEXP (exp, 0));
2371 if (address_used)
2372 return (*address_fn) (exp);
2373
2374 return attr_rtx (IF_THEN_ELSE,
2375 substitute_address (XEXP (exp, 0),
2376 no_address_fn, address_fn),
2377 substitute_address (XEXP (exp, 1),
2378 no_address_fn, address_fn),
2379 substitute_address (XEXP (exp, 2),
2380 no_address_fn, address_fn));
2381 }
2382
2383 return (*no_address_fn) (exp);
2384 }
2385 \f
2386 /* Make new attributes from the `length' attribute. The following are made,
2387 each corresponding to a function called from `shorten_branches' or
2388 `get_attr_length':
2389
2390 *insn_default_length This is the length of the insn to be returned
2391 by `get_attr_length' before `shorten_branches'
2392 has been called. In each case where the length
2393 depends on relative addresses, the largest
2394 possible is used. This routine is also used
2395 to compute the initial size of the insn.
2396
2397 *insn_variable_length_p This returns 1 if the insn's length depends
2398 on relative addresses, zero otherwise.
2399
2400 *insn_current_length This is only called when it is known that the
2401 insn has a variable length and returns the
2402 current length, based on relative addresses.
2403 */
2404
2405 static void
2406 make_length_attrs ()
2407 {
2408 static const char *new_names[] = {"*insn_default_length",
2409 "*insn_variable_length_p",
2410 "*insn_current_length"};
2411 static rtx (*no_address_fn[]) PROTO((rtx)) = {identity_fn, zero_fn, zero_fn};
2412 static rtx (*address_fn[]) PROTO((rtx)) = {max_fn, one_fn, identity_fn};
2413 size_t i;
2414 struct attr_desc *length_attr, *new_attr;
2415 struct attr_value *av, *new_av;
2416 struct insn_ent *ie, *new_ie;
2417
2418 /* See if length attribute is defined. If so, it must be numeric. Make
2419 it special so we don't output anything for it. */
2420 length_attr = find_attr ("length", 0);
2421 if (length_attr == 0)
2422 return;
2423
2424 if (! length_attr->is_numeric)
2425 fatal ("length attribute must be numeric.");
2426
2427 length_attr->is_const = 0;
2428 length_attr->is_special = 1;
2429
2430 /* Make each new attribute, in turn. */
2431 for (i = 0; i < sizeof new_names / sizeof new_names[0]; i++)
2432 {
2433 make_internal_attr (new_names[i],
2434 substitute_address (length_attr->default_val->value,
2435 no_address_fn[i], address_fn[i]),
2436 0);
2437 new_attr = find_attr (new_names[i], 0);
2438 for (av = length_attr->first_value; av; av = av->next)
2439 for (ie = av->first_insn; ie; ie = ie->next)
2440 {
2441 new_av = get_attr_value (substitute_address (av->value,
2442 no_address_fn[i],
2443 address_fn[i]),
2444 new_attr, ie->insn_code);
2445 new_ie = (struct insn_ent *) oballoc (sizeof (struct insn_ent));
2446 new_ie->insn_code = ie->insn_code;
2447 new_ie->insn_index = ie->insn_index;
2448 insert_insn_ent (new_av, new_ie);
2449 }
2450 }
2451 }
2452
2453 /* Utility functions called from above routine. */
2454
2455 static rtx
2456 identity_fn (exp)
2457 rtx exp;
2458 {
2459 return exp;
2460 }
2461
2462 static rtx
2463 zero_fn (exp)
2464 rtx exp ATTRIBUTE_UNUSED;
2465 {
2466 return make_numeric_value (0);
2467 }
2468
2469 static rtx
2470 one_fn (exp)
2471 rtx exp ATTRIBUTE_UNUSED;
2472 {
2473 return make_numeric_value (1);
2474 }
2475
2476 static rtx
2477 max_fn (exp)
2478 rtx exp;
2479 {
2480 int unknown;
2481 return make_numeric_value (max_attr_value (exp, &unknown));
2482 }
2483
2484 static void
2485 write_length_unit_log ()
2486 {
2487 struct attr_desc *length_attr = find_attr ("length", 0);
2488 struct attr_value *av;
2489 struct insn_ent *ie;
2490 unsigned int length_unit_log, length_or;
2491 int unknown = 0;
2492
2493 if (length_attr == 0)
2494 return;
2495 length_or = or_attr_value (length_attr->default_val->value, &unknown);
2496 for (av = length_attr->first_value; av; av = av->next)
2497 for (ie = av->first_insn; ie; ie = ie->next)
2498 length_or |= or_attr_value (av->value, &unknown);
2499
2500 if (unknown)
2501 length_unit_log = 0;
2502 else
2503 {
2504 length_or = ~length_or;
2505 for (length_unit_log = 0; length_or & 1; length_or >>= 1)
2506 length_unit_log++;
2507 }
2508 printf ("int length_unit_log = %u;\n", length_unit_log);
2509 }
2510 \f
2511 /* Take a COND expression and see if any of the conditions in it can be
2512 simplified. If any are known true or known false for the particular insn
2513 code, the COND can be further simplified.
2514
2515 Also call ourselves on any COND operations that are values of this COND.
2516
2517 We do not modify EXP; rather, we make and return a new rtx. */
2518
2519 static rtx
2520 simplify_cond (exp, insn_code, insn_index)
2521 rtx exp;
2522 int insn_code, insn_index;
2523 {
2524 int i, j;
2525 /* We store the desired contents here,
2526 then build a new expression if they don't match EXP. */
2527 rtx defval = XEXP (exp, 1);
2528 rtx new_defval = XEXP (exp, 1);
2529 int len = XVECLEN (exp, 0);
2530 rtunion *tests = (rtunion *) alloca (len * sizeof (rtunion));
2531 int allsame = 1;
2532 char *first_spacer;
2533
2534 /* This lets us free all storage allocated below, if appropriate. */
2535 first_spacer = (char *) obstack_finish (rtl_obstack);
2536
2537 bcopy ((char *) XVEC (exp, 0)->elem, (char *) tests, len * sizeof (rtunion));
2538
2539 /* See if default value needs simplification. */
2540 if (GET_CODE (defval) == COND)
2541 new_defval = simplify_cond (defval, insn_code, insn_index);
2542
2543 /* Simplify the subexpressions, and see what tests we can get rid of. */
2544
2545 for (i = 0; i < len; i += 2)
2546 {
2547 rtx newtest, newval;
2548
2549 /* Simplify this test. */
2550 newtest = SIMPLIFY_TEST_EXP (tests[i].rtx, insn_code, insn_index);
2551 tests[i].rtx = newtest;
2552
2553 newval = tests[i + 1].rtx;
2554 /* See if this value may need simplification. */
2555 if (GET_CODE (newval) == COND)
2556 newval = simplify_cond (newval, insn_code, insn_index);
2557
2558 /* Look for ways to delete or combine this test. */
2559 if (newtest == true_rtx)
2560 {
2561 /* If test is true, make this value the default
2562 and discard this + any following tests. */
2563 len = i;
2564 defval = tests[i + 1].rtx;
2565 new_defval = newval;
2566 }
2567
2568 else if (newtest == false_rtx)
2569 {
2570 /* If test is false, discard it and its value. */
2571 for (j = i; j < len - 2; j++)
2572 tests[j].rtx = tests[j + 2].rtx;
2573 len -= 2;
2574 }
2575
2576 else if (i > 0 && attr_equal_p (newval, tests[i - 1].rtx))
2577 {
2578 /* If this value and the value for the prev test are the same,
2579 merge the tests. */
2580
2581 tests[i - 2].rtx
2582 = insert_right_side (IOR, tests[i - 2].rtx, newtest,
2583 insn_code, insn_index);
2584
2585 /* Delete this test/value. */
2586 for (j = i; j < len - 2; j++)
2587 tests[j].rtx = tests[j + 2].rtx;
2588 len -= 2;
2589 }
2590
2591 else
2592 tests[i + 1].rtx = newval;
2593 }
2594
2595 /* If the last test in a COND has the same value
2596 as the default value, that test isn't needed. */
2597
2598 while (len > 0 && attr_equal_p (tests[len - 1].rtx, new_defval))
2599 len -= 2;
2600
2601 /* See if we changed anything. */
2602 if (len != XVECLEN (exp, 0) || new_defval != XEXP (exp, 1))
2603 allsame = 0;
2604 else
2605 for (i = 0; i < len; i++)
2606 if (! attr_equal_p (tests[i].rtx, XVECEXP (exp, 0, i)))
2607 {
2608 allsame = 0;
2609 break;
2610 }
2611
2612 if (len == 0)
2613 {
2614 if (!ggc_p)
2615 obstack_free (rtl_obstack, first_spacer);
2616 if (GET_CODE (defval) == COND)
2617 return simplify_cond (defval, insn_code, insn_index);
2618 return defval;
2619 }
2620 else if (allsame)
2621 {
2622 if (!ggc_p)
2623 obstack_free (rtl_obstack, first_spacer);
2624 return exp;
2625 }
2626 else
2627 {
2628 rtx newexp = rtx_alloc (COND);
2629
2630 XVEC (newexp, 0) = rtvec_alloc (len);
2631 bcopy ((char *) tests, (char *) XVEC (newexp, 0)->elem,
2632 len * sizeof (rtunion));
2633 XEXP (newexp, 1) = new_defval;
2634 return newexp;
2635 }
2636 }
2637 \f
2638 /* Remove an insn entry from an attribute value. */
2639
2640 static void
2641 remove_insn_ent (av, ie)
2642 struct attr_value *av;
2643 struct insn_ent *ie;
2644 {
2645 struct insn_ent *previe;
2646
2647 if (av->first_insn == ie)
2648 av->first_insn = ie->next;
2649 else
2650 {
2651 for (previe = av->first_insn; previe->next != ie; previe = previe->next)
2652 ;
2653 previe->next = ie->next;
2654 }
2655
2656 av->num_insns--;
2657 if (ie->insn_code == -1)
2658 av->has_asm_insn = 0;
2659
2660 num_insn_ents--;
2661 }
2662
2663 /* Insert an insn entry in an attribute value list. */
2664
2665 static void
2666 insert_insn_ent (av, ie)
2667 struct attr_value *av;
2668 struct insn_ent *ie;
2669 {
2670 ie->next = av->first_insn;
2671 av->first_insn = ie;
2672 av->num_insns++;
2673 if (ie->insn_code == -1)
2674 av->has_asm_insn = 1;
2675
2676 num_insn_ents++;
2677 }
2678 \f
2679 /* This is a utility routine to take an expression that is a tree of either
2680 AND or IOR expressions and insert a new term. The new term will be
2681 inserted at the right side of the first node whose code does not match
2682 the root. A new node will be created with the root's code. Its left
2683 side will be the old right side and its right side will be the new
2684 term.
2685
2686 If the `term' is itself a tree, all its leaves will be inserted. */
2687
2688 static rtx
2689 insert_right_side (code, exp, term, insn_code, insn_index)
2690 enum rtx_code code;
2691 rtx exp;
2692 rtx term;
2693 int insn_code, insn_index;
2694 {
2695 rtx newexp;
2696
2697 /* Avoid consing in some special cases. */
2698 if (code == AND && term == true_rtx)
2699 return exp;
2700 if (code == AND && term == false_rtx)
2701 return false_rtx;
2702 if (code == AND && exp == true_rtx)
2703 return term;
2704 if (code == AND && exp == false_rtx)
2705 return false_rtx;
2706 if (code == IOR && term == true_rtx)
2707 return true_rtx;
2708 if (code == IOR && term == false_rtx)
2709 return exp;
2710 if (code == IOR && exp == true_rtx)
2711 return true_rtx;
2712 if (code == IOR && exp == false_rtx)
2713 return term;
2714 if (attr_equal_p (exp, term))
2715 return exp;
2716
2717 if (GET_CODE (term) == code)
2718 {
2719 exp = insert_right_side (code, exp, XEXP (term, 0),
2720 insn_code, insn_index);
2721 exp = insert_right_side (code, exp, XEXP (term, 1),
2722 insn_code, insn_index);
2723
2724 return exp;
2725 }
2726
2727 if (GET_CODE (exp) == code)
2728 {
2729 rtx new = insert_right_side (code, XEXP (exp, 1),
2730 term, insn_code, insn_index);
2731 if (new != XEXP (exp, 1))
2732 /* Make a copy of this expression and call recursively. */
2733 newexp = attr_rtx (code, XEXP (exp, 0), new);
2734 else
2735 newexp = exp;
2736 }
2737 else
2738 {
2739 /* Insert the new term. */
2740 newexp = attr_rtx (code, exp, term);
2741 }
2742
2743 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2744 }
2745 \f
2746 /* If we have an expression which AND's a bunch of
2747 (not (eq_attrq "alternative" "n"))
2748 terms, we may have covered all or all but one of the possible alternatives.
2749 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
2750
2751 This routine is passed an expression and either AND or IOR. It returns a
2752 bitmask indicating which alternatives are mentioned within EXP. */
2753
2754 static int
2755 compute_alternative_mask (exp, code)
2756 rtx exp;
2757 enum rtx_code code;
2758 {
2759 char *string;
2760 if (GET_CODE (exp) == code)
2761 return compute_alternative_mask (XEXP (exp, 0), code)
2762 | compute_alternative_mask (XEXP (exp, 1), code);
2763
2764 else if (code == AND && GET_CODE (exp) == NOT
2765 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
2766 && XSTR (XEXP (exp, 0), 0) == alternative_name)
2767 string = XSTR (XEXP (exp, 0), 1);
2768
2769 else if (code == IOR && GET_CODE (exp) == EQ_ATTR
2770 && XSTR (exp, 0) == alternative_name)
2771 string = XSTR (exp, 1);
2772
2773 else
2774 return 0;
2775
2776 if (string[1] == 0)
2777 return 1 << (string[0] - '0');
2778 return 1 << atoi (string);
2779 }
2780
2781 /* Given I, a single-bit mask, return RTX to compare the `alternative'
2782 attribute with the value represented by that bit. */
2783
2784 static rtx
2785 make_alternative_compare (mask)
2786 int mask;
2787 {
2788 rtx newexp;
2789 int i;
2790
2791 /* Find the bit. */
2792 for (i = 0; (mask & (1 << i)) == 0; i++)
2793 ;
2794
2795 newexp = attr_rtx (EQ_ATTR, alternative_name, attr_numeral (i));
2796 RTX_UNCHANGING_P (newexp) = 1;
2797
2798 return newexp;
2799 }
2800 \f
2801 /* If we are processing an (eq_attr "attr" "value") test, we find the value
2802 of "attr" for this insn code. From that value, we can compute a test
2803 showing when the EQ_ATTR will be true. This routine performs that
2804 computation. If a test condition involves an address, we leave the EQ_ATTR
2805 intact because addresses are only valid for the `length' attribute.
2806
2807 EXP is the EQ_ATTR expression and VALUE is the value of that attribute
2808 for the insn corresponding to INSN_CODE and INSN_INDEX. */
2809
2810 static rtx
2811 evaluate_eq_attr (exp, value, insn_code, insn_index)
2812 rtx exp;
2813 rtx value;
2814 int insn_code, insn_index;
2815 {
2816 rtx orexp, andexp;
2817 rtx right;
2818 rtx newexp;
2819 int i;
2820
2821 if (GET_CODE (value) == CONST_STRING)
2822 {
2823 if (! strcmp (XSTR (value, 0), XSTR (exp, 1)))
2824 newexp = true_rtx;
2825 else
2826 newexp = false_rtx;
2827 }
2828 else if (GET_CODE (value) == SYMBOL_REF)
2829 {
2830 char *p, *string;
2831
2832 if (GET_CODE (exp) != EQ_ATTR)
2833 abort();
2834
2835 string = (char *) alloca (2 + strlen (XSTR (exp, 0))
2836 + strlen (XSTR (exp, 1)));
2837 strcpy (string, XSTR (exp, 0));
2838 strcat (string, "_");
2839 strcat (string, XSTR (exp, 1));
2840 for (p = string; *p ; p++)
2841 if (ISLOWER(*p))
2842 *p = toupper (*p);
2843
2844 newexp = attr_rtx (EQ, value,
2845 attr_rtx (SYMBOL_REF,
2846 attr_string(string, strlen(string))));
2847 }
2848 else if (GET_CODE (value) == COND)
2849 {
2850 /* We construct an IOR of all the cases for which the requested attribute
2851 value is present. Since we start with FALSE, if it is not present,
2852 FALSE will be returned.
2853
2854 Each case is the AND of the NOT's of the previous conditions with the
2855 current condition; in the default case the current condition is TRUE.
2856
2857 For each possible COND value, call ourselves recursively.
2858
2859 The extra TRUE and FALSE expressions will be eliminated by another
2860 call to the simplification routine. */
2861
2862 orexp = false_rtx;
2863 andexp = true_rtx;
2864
2865 if (current_alternative_string)
2866 clear_struct_flag (value);
2867
2868 for (i = 0; i < XVECLEN (value, 0); i += 2)
2869 {
2870 rtx this = SIMPLIFY_TEST_EXP (XVECEXP (value, 0, i),
2871 insn_code, insn_index);
2872
2873 SIMPLIFY_ALTERNATIVE (this);
2874
2875 right = insert_right_side (AND, andexp, this,
2876 insn_code, insn_index);
2877 right = insert_right_side (AND, right,
2878 evaluate_eq_attr (exp,
2879 XVECEXP (value, 0,
2880 i + 1),
2881 insn_code, insn_index),
2882 insn_code, insn_index);
2883 orexp = insert_right_side (IOR, orexp, right,
2884 insn_code, insn_index);
2885
2886 /* Add this condition into the AND expression. */
2887 newexp = attr_rtx (NOT, this);
2888 andexp = insert_right_side (AND, andexp, newexp,
2889 insn_code, insn_index);
2890 }
2891
2892 /* Handle the default case. */
2893 right = insert_right_side (AND, andexp,
2894 evaluate_eq_attr (exp, XEXP (value, 1),
2895 insn_code, insn_index),
2896 insn_code, insn_index);
2897 newexp = insert_right_side (IOR, orexp, right, insn_code, insn_index);
2898 }
2899 else
2900 abort ();
2901
2902 /* If uses an address, must return original expression. But set the
2903 RTX_UNCHANGING_P bit so we don't try to simplify it again. */
2904
2905 address_used = 0;
2906 walk_attr_value (newexp);
2907
2908 if (address_used)
2909 {
2910 /* This had `&& current_alternative_string', which seems to be wrong. */
2911 if (! RTX_UNCHANGING_P (exp))
2912 return copy_rtx_unchanging (exp);
2913 return exp;
2914 }
2915 else
2916 return newexp;
2917 }
2918 \f
2919 /* This routine is called when an AND of a term with a tree of AND's is
2920 encountered. If the term or its complement is present in the tree, it
2921 can be replaced with TRUE or FALSE, respectively.
2922
2923 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2924 be true and hence are complementary.
2925
2926 There is one special case: If we see
2927 (and (not (eq_attr "att" "v1"))
2928 (eq_attr "att" "v2"))
2929 this can be replaced by (eq_attr "att" "v2"). To do this we need to
2930 replace the term, not anything in the AND tree. So we pass a pointer to
2931 the term. */
2932
2933 static rtx
2934 simplify_and_tree (exp, pterm, insn_code, insn_index)
2935 rtx exp;
2936 rtx *pterm;
2937 int insn_code, insn_index;
2938 {
2939 rtx left, right;
2940 rtx newexp;
2941 rtx temp;
2942 int left_eliminates_term, right_eliminates_term;
2943
2944 if (GET_CODE (exp) == AND)
2945 {
2946 left = simplify_and_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
2947 right = simplify_and_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2948 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2949 {
2950 newexp = attr_rtx (GET_CODE (exp), left, right);
2951
2952 exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2953 }
2954 }
2955
2956 else if (GET_CODE (exp) == IOR)
2957 {
2958 /* For the IOR case, we do the same as above, except that we can
2959 only eliminate `term' if both sides of the IOR would do so. */
2960 temp = *pterm;
2961 left = simplify_and_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
2962 left_eliminates_term = (temp == true_rtx);
2963
2964 temp = *pterm;
2965 right = simplify_and_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2966 right_eliminates_term = (temp == true_rtx);
2967
2968 if (left_eliminates_term && right_eliminates_term)
2969 *pterm = true_rtx;
2970
2971 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2972 {
2973 newexp = attr_rtx (GET_CODE (exp), left, right);
2974
2975 exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2976 }
2977 }
2978
2979 /* Check for simplifications. Do some extra checking here since this
2980 routine is called so many times. */
2981
2982 if (exp == *pterm)
2983 return true_rtx;
2984
2985 else if (GET_CODE (exp) == NOT && XEXP (exp, 0) == *pterm)
2986 return false_rtx;
2987
2988 else if (GET_CODE (*pterm) == NOT && exp == XEXP (*pterm, 0))
2989 return false_rtx;
2990
2991 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == EQ_ATTR)
2992 {
2993 if (XSTR (exp, 0) != XSTR (*pterm, 0))
2994 return exp;
2995
2996 if (! strcmp (XSTR (exp, 1), XSTR (*pterm, 1)))
2997 return true_rtx;
2998 else
2999 return false_rtx;
3000 }
3001
3002 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
3003 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
3004 {
3005 if (XSTR (*pterm, 0) != XSTR (XEXP (exp, 0), 0))
3006 return exp;
3007
3008 if (! strcmp (XSTR (*pterm, 1), XSTR (XEXP (exp, 0), 1)))
3009 return false_rtx;
3010 else
3011 return true_rtx;
3012 }
3013
3014 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
3015 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR)
3016 {
3017 if (XSTR (exp, 0) != XSTR (XEXP (*pterm, 0), 0))
3018 return exp;
3019
3020 if (! strcmp (XSTR (exp, 1), XSTR (XEXP (*pterm, 0), 1)))
3021 return false_rtx;
3022 else
3023 *pterm = true_rtx;
3024 }
3025
3026 else if (GET_CODE (exp) == NOT && GET_CODE (*pterm) == NOT)
3027 {
3028 if (attr_equal_p (XEXP (exp, 0), XEXP (*pterm, 0)))
3029 return true_rtx;
3030 }
3031
3032 else if (GET_CODE (exp) == NOT)
3033 {
3034 if (attr_equal_p (XEXP (exp, 0), *pterm))
3035 return false_rtx;
3036 }
3037
3038 else if (GET_CODE (*pterm) == NOT)
3039 {
3040 if (attr_equal_p (XEXP (*pterm, 0), exp))
3041 return false_rtx;
3042 }
3043
3044 else if (attr_equal_p (exp, *pterm))
3045 return true_rtx;
3046
3047 return exp;
3048 }
3049 \f
3050 /* Similar to `simplify_and_tree', but for IOR trees. */
3051
3052 static rtx
3053 simplify_or_tree (exp, pterm, insn_code, insn_index)
3054 rtx exp;
3055 rtx *pterm;
3056 int insn_code, insn_index;
3057 {
3058 rtx left, right;
3059 rtx newexp;
3060 rtx temp;
3061 int left_eliminates_term, right_eliminates_term;
3062
3063 if (GET_CODE (exp) == IOR)
3064 {
3065 left = simplify_or_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
3066 right = simplify_or_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
3067 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3068 {
3069 newexp = attr_rtx (GET_CODE (exp), left, right);
3070
3071 exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3072 }
3073 }
3074
3075 else if (GET_CODE (exp) == AND)
3076 {
3077 /* For the AND case, we do the same as above, except that we can
3078 only eliminate `term' if both sides of the AND would do so. */
3079 temp = *pterm;
3080 left = simplify_or_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
3081 left_eliminates_term = (temp == false_rtx);
3082
3083 temp = *pterm;
3084 right = simplify_or_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
3085 right_eliminates_term = (temp == false_rtx);
3086
3087 if (left_eliminates_term && right_eliminates_term)
3088 *pterm = false_rtx;
3089
3090 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3091 {
3092 newexp = attr_rtx (GET_CODE (exp), left, right);
3093
3094 exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3095 }
3096 }
3097
3098 if (attr_equal_p (exp, *pterm))
3099 return false_rtx;
3100
3101 else if (GET_CODE (exp) == NOT && attr_equal_p (XEXP (exp, 0), *pterm))
3102 return true_rtx;
3103
3104 else if (GET_CODE (*pterm) == NOT && attr_equal_p (XEXP (*pterm, 0), exp))
3105 return true_rtx;
3106
3107 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
3108 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
3109 && XSTR (*pterm, 0) == XSTR (XEXP (exp, 0), 0))
3110 *pterm = false_rtx;
3111
3112 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
3113 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR
3114 && XSTR (exp, 0) == XSTR (XEXP (*pterm, 0), 0))
3115 return false_rtx;
3116
3117 return exp;
3118 }
3119 \f
3120 /* Given an expression, see if it can be simplified for a particular insn
3121 code based on the values of other attributes being tested. This can
3122 eliminate nested get_attr_... calls.
3123
3124 Note that if an endless recursion is specified in the patterns, the
3125 optimization will loop. However, it will do so in precisely the cases where
3126 an infinite recursion loop could occur during compilation. It's better that
3127 it occurs here! */
3128
3129 static rtx
3130 simplify_test_exp (exp, insn_code, insn_index)
3131 rtx exp;
3132 int insn_code, insn_index;
3133 {
3134 rtx left, right;
3135 struct attr_desc *attr;
3136 struct attr_value *av;
3137 struct insn_ent *ie;
3138 int i;
3139 rtx newexp = exp;
3140 char *spacer = (char *) obstack_finish (rtl_obstack);
3141
3142 /* Don't re-simplify something we already simplified. */
3143 if (RTX_UNCHANGING_P (exp) || MEM_IN_STRUCT_P (exp))
3144 return exp;
3145
3146 switch (GET_CODE (exp))
3147 {
3148 case AND:
3149 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
3150 SIMPLIFY_ALTERNATIVE (left);
3151 if (left == false_rtx)
3152 {
3153 if (!ggc_p)
3154 obstack_free (rtl_obstack, spacer);
3155 return false_rtx;
3156 }
3157 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
3158 SIMPLIFY_ALTERNATIVE (right);
3159 if (left == false_rtx)
3160 {
3161 if (!ggc_p)
3162 obstack_free (rtl_obstack, spacer);
3163 return false_rtx;
3164 }
3165
3166 /* If either side is an IOR and we have (eq_attr "alternative" ..")
3167 present on both sides, apply the distributive law since this will
3168 yield simplifications. */
3169 if ((GET_CODE (left) == IOR || GET_CODE (right) == IOR)
3170 && compute_alternative_mask (left, IOR)
3171 && compute_alternative_mask (right, IOR))
3172 {
3173 if (GET_CODE (left) == IOR)
3174 {
3175 rtx tem = left;
3176 left = right;
3177 right = tem;
3178 }
3179
3180 newexp = attr_rtx (IOR,
3181 attr_rtx (AND, left, XEXP (right, 0)),
3182 attr_rtx (AND, left, XEXP (right, 1)));
3183
3184 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3185 }
3186
3187 /* Try with the term on both sides. */
3188 right = simplify_and_tree (right, &left, insn_code, insn_index);
3189 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
3190 left = simplify_and_tree (left, &right, insn_code, insn_index);
3191
3192 if (left == false_rtx || right == false_rtx)
3193 {
3194 if (!ggc_p)
3195 obstack_free (rtl_obstack, spacer);
3196 return false_rtx;
3197 }
3198 else if (left == true_rtx)
3199 {
3200 return right;
3201 }
3202 else if (right == true_rtx)
3203 {
3204 return left;
3205 }
3206 /* See if all or all but one of the insn's alternatives are specified
3207 in this tree. Optimize if so. */
3208
3209 else if (insn_code >= 0
3210 && (GET_CODE (left) == AND
3211 || (GET_CODE (left) == NOT
3212 && GET_CODE (XEXP (left, 0)) == EQ_ATTR
3213 && XSTR (XEXP (left, 0), 0) == alternative_name)
3214 || GET_CODE (right) == AND
3215 || (GET_CODE (right) == NOT
3216 && GET_CODE (XEXP (right, 0)) == EQ_ATTR
3217 && XSTR (XEXP (right, 0), 0) == alternative_name)))
3218 {
3219 i = compute_alternative_mask (exp, AND);
3220 if (i & ~insn_alternatives[insn_code])
3221 fatal ("Invalid alternative specified for pattern number %d",
3222 insn_index);
3223
3224 /* If all alternatives are excluded, this is false. */
3225 i ^= insn_alternatives[insn_code];
3226 if (i == 0)
3227 return false_rtx;
3228 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
3229 {
3230 /* If just one excluded, AND a comparison with that one to the
3231 front of the tree. The others will be eliminated by
3232 optimization. We do not want to do this if the insn has one
3233 alternative and we have tested none of them! */
3234 left = make_alternative_compare (i);
3235 right = simplify_and_tree (exp, &left, insn_code, insn_index);
3236 newexp = attr_rtx (AND, left, right);
3237
3238 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3239 }
3240 }
3241
3242 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3243 {
3244 newexp = attr_rtx (AND, left, right);
3245 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3246 }
3247 break;
3248
3249 case IOR:
3250 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
3251 SIMPLIFY_ALTERNATIVE (left);
3252 if (left == true_rtx)
3253 {
3254 if (!ggc_p)
3255 obstack_free (rtl_obstack, spacer);
3256 return true_rtx;
3257 }
3258 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
3259 SIMPLIFY_ALTERNATIVE (right);
3260 if (right == true_rtx)
3261 {
3262 if (!ggc_p)
3263 obstack_free (rtl_obstack, spacer);
3264 return true_rtx;
3265 }
3266
3267 right = simplify_or_tree (right, &left, insn_code, insn_index);
3268 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
3269 left = simplify_or_tree (left, &right, insn_code, insn_index);
3270
3271 if (right == true_rtx || left == true_rtx)
3272 {
3273 if (!ggc_p)
3274 obstack_free (rtl_obstack, spacer);
3275 return true_rtx;
3276 }
3277 else if (left == false_rtx)
3278 {
3279 return right;
3280 }
3281 else if (right == false_rtx)
3282 {
3283 return left;
3284 }
3285
3286 /* Test for simple cases where the distributive law is useful. I.e.,
3287 convert (ior (and (x) (y))
3288 (and (x) (z)))
3289 to (and (x)
3290 (ior (y) (z)))
3291 */
3292
3293 else if (GET_CODE (left) == AND && GET_CODE (right) == AND
3294 && attr_equal_p (XEXP (left, 0), XEXP (right, 0)))
3295 {
3296 newexp = attr_rtx (IOR, XEXP (left, 1), XEXP (right, 1));
3297
3298 left = XEXP (left, 0);
3299 right = newexp;
3300 newexp = attr_rtx (AND, left, right);
3301 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3302 }
3303
3304 /* See if all or all but one of the insn's alternatives are specified
3305 in this tree. Optimize if so. */
3306
3307 else if (insn_code >= 0
3308 && (GET_CODE (left) == IOR
3309 || (GET_CODE (left) == EQ_ATTR
3310 && XSTR (left, 0) == alternative_name)
3311 || GET_CODE (right) == IOR
3312 || (GET_CODE (right) == EQ_ATTR
3313 && XSTR (right, 0) == alternative_name)))
3314 {
3315 i = compute_alternative_mask (exp, IOR);
3316 if (i & ~insn_alternatives[insn_code])
3317 fatal ("Invalid alternative specified for pattern number %d",
3318 insn_index);
3319
3320 /* If all alternatives are included, this is true. */
3321 i ^= insn_alternatives[insn_code];
3322 if (i == 0)
3323 return true_rtx;
3324 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
3325 {
3326 /* If just one excluded, IOR a comparison with that one to the
3327 front of the tree. The others will be eliminated by
3328 optimization. We do not want to do this if the insn has one
3329 alternative and we have tested none of them! */
3330 left = make_alternative_compare (i);
3331 right = simplify_and_tree (exp, &left, insn_code, insn_index);
3332 newexp = attr_rtx (IOR, attr_rtx (NOT, left), right);
3333
3334 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3335 }
3336 }
3337
3338 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3339 {
3340 newexp = attr_rtx (IOR, left, right);
3341 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3342 }
3343 break;
3344
3345 case NOT:
3346 if (GET_CODE (XEXP (exp, 0)) == NOT)
3347 {
3348 left = SIMPLIFY_TEST_EXP (XEXP (XEXP (exp, 0), 0),
3349 insn_code, insn_index);
3350 SIMPLIFY_ALTERNATIVE (left);
3351 return left;
3352 }
3353
3354 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
3355 SIMPLIFY_ALTERNATIVE (left);
3356 if (GET_CODE (left) == NOT)
3357 return XEXP (left, 0);
3358
3359 if (left == false_rtx)
3360 {
3361 if (!ggc_p)
3362 obstack_free (rtl_obstack, spacer);
3363 return true_rtx;
3364 }
3365 else if (left == true_rtx)
3366 {
3367 if (!ggc_p)
3368 obstack_free (rtl_obstack, spacer);
3369 return false_rtx;
3370 }
3371
3372 /* Try to apply De`Morgan's laws. */
3373 else if (GET_CODE (left) == IOR)
3374 {
3375 newexp = attr_rtx (AND,
3376 attr_rtx (NOT, XEXP (left, 0)),
3377 attr_rtx (NOT, XEXP (left, 1)));
3378
3379 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3380 }
3381 else if (GET_CODE (left) == AND)
3382 {
3383 newexp = attr_rtx (IOR,
3384 attr_rtx (NOT, XEXP (left, 0)),
3385 attr_rtx (NOT, XEXP (left, 1)));
3386
3387 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3388 }
3389 else if (left != XEXP (exp, 0))
3390 {
3391 newexp = attr_rtx (NOT, left);
3392 }
3393 break;
3394
3395 case EQ_ATTR:
3396 if (current_alternative_string && XSTR (exp, 0) == alternative_name)
3397 return (XSTR (exp, 1) == current_alternative_string
3398 ? true_rtx : false_rtx);
3399
3400 /* Look at the value for this insn code in the specified attribute.
3401 We normally can replace this comparison with the condition that
3402 would give this insn the values being tested for. */
3403 if (XSTR (exp, 0) != alternative_name
3404 && (attr = find_attr (XSTR (exp, 0), 0)) != NULL)
3405 for (av = attr->first_value; av; av = av->next)
3406 for (ie = av->first_insn; ie; ie = ie->next)
3407 if (ie->insn_code == insn_code)
3408 return evaluate_eq_attr (exp, av->value, insn_code, insn_index);
3409 break;
3410
3411 default:
3412 break;
3413 }
3414
3415 /* We have already simplified this expression. Simplifying it again
3416 won't buy anything unless we weren't given a valid insn code
3417 to process (i.e., we are canonicalizing something.). */
3418 if (insn_code != -2 /* Seems wrong: && current_alternative_string. */
3419 && ! RTX_UNCHANGING_P (newexp))
3420 return copy_rtx_unchanging (newexp);
3421
3422 return newexp;
3423 }
3424 \f
3425 /* Optimize the attribute lists by seeing if we can determine conditional
3426 values from the known values of other attributes. This will save subroutine
3427 calls during the compilation. */
3428
3429 static void
3430 optimize_attrs ()
3431 {
3432 struct attr_desc *attr;
3433 struct attr_value *av;
3434 struct insn_ent *ie;
3435 rtx newexp;
3436 int something_changed = 1;
3437 int i;
3438 struct attr_value_list { struct attr_value *av;
3439 struct insn_ent *ie;
3440 struct attr_desc * attr;
3441 struct attr_value_list *next; };
3442 struct attr_value_list **insn_code_values;
3443 struct attr_value_list *ivbuf;
3444 struct attr_value_list *iv;
3445
3446 /* For each insn code, make a list of all the insn_ent's for it,
3447 for all values for all attributes. */
3448
3449 if (num_insn_ents == 0)
3450 return;
3451
3452 /* Make 2 extra elements, for "code" values -2 and -1. */
3453 insn_code_values
3454 = (struct attr_value_list **) alloca ((insn_code_number + 2)
3455 * sizeof (struct attr_value_list *));
3456 bzero ((char *) insn_code_values,
3457 (insn_code_number + 2) * sizeof (struct attr_value_list *));
3458
3459 /* Offset the table address so we can index by -2 or -1. */
3460 insn_code_values += 2;
3461
3462 /* Allocate the attr_value_list structures using xmalloc rather than
3463 alloca, because using alloca can overflow the maximum permitted
3464 stack limit on SPARC Lynx. */
3465 iv = ivbuf = ((struct attr_value_list *)
3466 xmalloc (num_insn_ents * sizeof (struct attr_value_list)));
3467
3468 for (i = 0; i < MAX_ATTRS_INDEX; i++)
3469 for (attr = attrs[i]; attr; attr = attr->next)
3470 for (av = attr->first_value; av; av = av->next)
3471 for (ie = av->first_insn; ie; ie = ie->next)
3472 {
3473 iv->attr = attr;
3474 iv->av = av;
3475 iv->ie = ie;
3476 iv->next = insn_code_values[ie->insn_code];
3477 insn_code_values[ie->insn_code] = iv;
3478 iv++;
3479 }
3480
3481 /* Sanity check on num_insn_ents. */
3482 if (iv != ivbuf + num_insn_ents)
3483 abort ();
3484
3485 /* Process one insn code at a time. */
3486 for (i = -2; i < insn_code_number; i++)
3487 {
3488 /* Clear the MEM_IN_STRUCT_P flag everywhere relevant.
3489 We use it to mean "already simplified for this insn". */
3490 for (iv = insn_code_values[i]; iv; iv = iv->next)
3491 clear_struct_flag (iv->av->value);
3492
3493 /* Loop until nothing changes for one iteration. */
3494 something_changed = 1;
3495 while (something_changed)
3496 {
3497 something_changed = 0;
3498 for (iv = insn_code_values[i]; iv; iv = iv->next)
3499 {
3500 struct obstack *old = rtl_obstack;
3501 char *spacer = (char *) obstack_finish (temp_obstack);
3502
3503 attr = iv->attr;
3504 av = iv->av;
3505 ie = iv->ie;
3506 if (GET_CODE (av->value) != COND)
3507 continue;
3508
3509 rtl_obstack = temp_obstack;
3510 #if 0 /* This was intended as a speed up, but it was slower. */
3511 if (insn_n_alternatives[ie->insn_code] > 6
3512 && count_sub_rtxs (av->value, 200) >= 200)
3513 newexp = simplify_by_alternatives (av->value, ie->insn_code,
3514 ie->insn_index);
3515 else
3516 #endif
3517 newexp = simplify_cond (av->value, ie->insn_code,
3518 ie->insn_index);
3519
3520 rtl_obstack = old;
3521 if (newexp != av->value)
3522 {
3523 newexp = attr_copy_rtx (newexp);
3524 remove_insn_ent (av, ie);
3525 av = get_attr_value (newexp, attr, ie->insn_code);
3526 iv->av = av;
3527 insert_insn_ent (av, ie);
3528 something_changed = 1;
3529 }
3530 if (!ggc_p)
3531 obstack_free (temp_obstack, spacer);
3532 }
3533 }
3534 }
3535
3536 free (ivbuf);
3537 }
3538
3539 #if 0
3540 static rtx
3541 simplify_by_alternatives (exp, insn_code, insn_index)
3542 rtx exp;
3543 int insn_code, insn_index;
3544 {
3545 int i;
3546 int len = insn_n_alternatives[insn_code];
3547 rtx newexp = rtx_alloc (COND);
3548 rtx ultimate;
3549
3550
3551 XVEC (newexp, 0) = rtvec_alloc (len * 2);
3552
3553 /* It will not matter what value we use as the default value
3554 of the new COND, since that default will never be used.
3555 Choose something of the right type. */
3556 for (ultimate = exp; GET_CODE (ultimate) == COND;)
3557 ultimate = XEXP (ultimate, 1);
3558 XEXP (newexp, 1) = ultimate;
3559
3560 for (i = 0; i < insn_n_alternatives[insn_code]; i++)
3561 {
3562 current_alternative_string = attr_numeral (i);
3563 XVECEXP (newexp, 0, i * 2) = make_alternative_compare (1 << i);
3564 XVECEXP (newexp, 0, i * 2 + 1)
3565 = simplify_cond (exp, insn_code, insn_index);
3566 }
3567
3568 current_alternative_string = 0;
3569 return simplify_cond (newexp, insn_code, insn_index);
3570 }
3571 #endif
3572 \f
3573 /* If EXP is a suitable expression, reorganize it by constructing an
3574 equivalent expression that is a COND with the tests being all combinations
3575 of attribute values and the values being simple constants. */
3576
3577 static rtx
3578 simplify_by_exploding (exp)
3579 rtx exp;
3580 {
3581 rtx list = 0, link, condexp, defval = NULL_RTX;
3582 struct dimension *space;
3583 rtx *condtest, *condval;
3584 int i, j, total, ndim = 0;
3585 int most_tests, num_marks, new_marks;
3586
3587 /* Locate all the EQ_ATTR expressions. */
3588 if (! find_and_mark_used_attributes (exp, &list, &ndim) || ndim == 0)
3589 {
3590 unmark_used_attributes (list, 0, 0);
3591 return exp;
3592 }
3593
3594 /* Create an attribute space from the list of used attributes. For each
3595 dimension in the attribute space, record the attribute, list of values
3596 used, and number of values used. Add members to the list of values to
3597 cover the domain of the attribute. This makes the expanded COND form
3598 order independent. */
3599
3600 space = (struct dimension *) alloca (ndim * sizeof (struct dimension));
3601
3602 total = 1;
3603 for (ndim = 0; list; ndim++)
3604 {
3605 /* Pull the first attribute value from the list and record that
3606 attribute as another dimension in the attribute space. */
3607 char *name = XSTR (XEXP (list, 0), 0);
3608 rtx *prev;
3609
3610 if ((space[ndim].attr = find_attr (name, 0)) == 0
3611 || space[ndim].attr->is_numeric)
3612 {
3613 unmark_used_attributes (list, space, ndim);
3614 return exp;
3615 }
3616
3617 /* Add all remaining attribute values that refer to this attribute. */
3618 space[ndim].num_values = 0;
3619 space[ndim].values = 0;
3620 prev = &list;
3621 for (link = list; link; link = *prev)
3622 if (! strcmp (XSTR (XEXP (link, 0), 0), name))
3623 {
3624 space[ndim].num_values++;
3625 *prev = XEXP (link, 1);
3626 XEXP (link, 1) = space[ndim].values;
3627 space[ndim].values = link;
3628 }
3629 else
3630 prev = &XEXP (link, 1);
3631
3632 /* Add sufficient members to the list of values to make the list
3633 mutually exclusive and record the total size of the attribute
3634 space. */
3635 total *= add_values_to_cover (&space[ndim]);
3636 }
3637
3638 /* Sort the attribute space so that the attributes go from non-constant
3639 to constant and from most values to least values. */
3640 for (i = 0; i < ndim; i++)
3641 for (j = ndim - 1; j > i; j--)
3642 if ((space[j-1].attr->is_const && !space[j].attr->is_const)
3643 || space[j-1].num_values < space[j].num_values)
3644 {
3645 struct dimension tmp;
3646 tmp = space[j];
3647 space[j] = space[j-1];
3648 space[j-1] = tmp;
3649 }
3650
3651 /* Establish the initial current value. */
3652 for (i = 0; i < ndim; i++)
3653 space[i].current_value = space[i].values;
3654
3655 condtest = (rtx *) alloca (total * sizeof (rtx));
3656 condval = (rtx *) alloca (total * sizeof (rtx));
3657
3658 /* Expand the tests and values by iterating over all values in the
3659 attribute space. */
3660 for (i = 0;; i++)
3661 {
3662 condtest[i] = test_for_current_value (space, ndim);
3663 condval[i] = simplify_with_current_value (exp, space, ndim);
3664 if (! increment_current_value (space, ndim))
3665 break;
3666 }
3667 if (i != total - 1)
3668 abort ();
3669
3670 /* We are now finished with the original expression. */
3671 unmark_used_attributes (0, space, ndim);
3672
3673 /* Find the most used constant value and make that the default. */
3674 most_tests = -1;
3675 for (i = num_marks = 0; i < total; i++)
3676 if (GET_CODE (condval[i]) == CONST_STRING
3677 && ! MEM_VOLATILE_P (condval[i]))
3678 {
3679 /* Mark the unmarked constant value and count how many are marked. */
3680 MEM_VOLATILE_P (condval[i]) = 1;
3681 for (j = new_marks = 0; j < total; j++)
3682 if (GET_CODE (condval[j]) == CONST_STRING
3683 && MEM_VOLATILE_P (condval[j]))
3684 new_marks++;
3685 if (new_marks - num_marks > most_tests)
3686 {
3687 most_tests = new_marks - num_marks;
3688 defval = condval[i];
3689 }
3690 num_marks = new_marks;
3691 }
3692 /* Clear all the marks. */
3693 for (i = 0; i < total; i++)
3694 MEM_VOLATILE_P (condval[i]) = 0;
3695
3696 /* Give up if nothing is constant. */
3697 if (num_marks == 0)
3698 return exp;
3699
3700 /* If all values are the default, use that. */
3701 if (total == most_tests)
3702 return defval;
3703
3704 /* Make a COND with the most common constant value the default. (A more
3705 complex method where tests with the same value were combined didn't
3706 seem to improve things.) */
3707 condexp = rtx_alloc (COND);
3708 XVEC (condexp, 0) = rtvec_alloc ((total - most_tests) * 2);
3709 XEXP (condexp, 1) = defval;
3710 for (i = j = 0; i < total; i++)
3711 if (condval[i] != defval)
3712 {
3713 XVECEXP (condexp, 0, 2 * j) = condtest[i];
3714 XVECEXP (condexp, 0, 2 * j + 1) = condval[i];
3715 j++;
3716 }
3717
3718 return condexp;
3719 }
3720
3721 /* Set the MEM_VOLATILE_P flag for all EQ_ATTR expressions in EXP and
3722 verify that EXP can be simplified to a constant term if all the EQ_ATTR
3723 tests have known value. */
3724
3725 static int
3726 find_and_mark_used_attributes (exp, terms, nterms)
3727 rtx exp, *terms;
3728 int *nterms;
3729 {
3730 int i;
3731
3732 switch (GET_CODE (exp))
3733 {
3734 case EQ_ATTR:
3735 if (! MEM_VOLATILE_P (exp))
3736 {
3737 rtx link = rtx_alloc (EXPR_LIST);
3738 XEXP (link, 0) = exp;
3739 XEXP (link, 1) = *terms;
3740 *terms = link;
3741 *nterms += 1;
3742 MEM_VOLATILE_P (exp) = 1;
3743 }
3744 return 1;
3745
3746 case CONST_STRING:
3747 case CONST_INT:
3748 return 1;
3749
3750 case IF_THEN_ELSE:
3751 if (! find_and_mark_used_attributes (XEXP (exp, 2), terms, nterms))
3752 return 0;
3753 case IOR:
3754 case AND:
3755 if (! find_and_mark_used_attributes (XEXP (exp, 1), terms, nterms))
3756 return 0;
3757 case NOT:
3758 if (! find_and_mark_used_attributes (XEXP (exp, 0), terms, nterms))
3759 return 0;
3760 return 1;
3761
3762 case COND:
3763 for (i = 0; i < XVECLEN (exp, 0); i++)
3764 if (! find_and_mark_used_attributes (XVECEXP (exp, 0, i), terms, nterms))
3765 return 0;
3766 if (! find_and_mark_used_attributes (XEXP (exp, 1), terms, nterms))
3767 return 0;
3768 return 1;
3769
3770 default:
3771 return 0;
3772 }
3773 }
3774
3775 /* Clear the MEM_VOLATILE_P flag in all EQ_ATTR expressions on LIST and
3776 in the values of the NDIM-dimensional attribute space SPACE. */
3777
3778 static void
3779 unmark_used_attributes (list, space, ndim)
3780 rtx list;
3781 struct dimension *space;
3782 int ndim;
3783 {
3784 rtx link, exp;
3785 int i;
3786
3787 for (i = 0; i < ndim; i++)
3788 unmark_used_attributes (space[i].values, 0, 0);
3789
3790 for (link = list; link; link = XEXP (link, 1))
3791 {
3792 exp = XEXP (link, 0);
3793 if (GET_CODE (exp) == EQ_ATTR)
3794 MEM_VOLATILE_P (exp) = 0;
3795 }
3796 }
3797
3798 /* Update the attribute dimension DIM so that all values of the attribute
3799 are tested. Return the updated number of values. */
3800
3801 static int
3802 add_values_to_cover (dim)
3803 struct dimension *dim;
3804 {
3805 struct attr_value *av;
3806 rtx exp, link, *prev;
3807 int nalt = 0;
3808
3809 for (av = dim->attr->first_value; av; av = av->next)
3810 if (GET_CODE (av->value) == CONST_STRING)
3811 nalt++;
3812
3813 if (nalt < dim->num_values)
3814 abort ();
3815 else if (nalt == dim->num_values)
3816 ; /* Ok. */
3817 else if (nalt * 2 < dim->num_values * 3)
3818 {
3819 /* Most all the values of the attribute are used, so add all the unused
3820 values. */
3821 prev = &dim->values;
3822 for (link = dim->values; link; link = *prev)
3823 prev = &XEXP (link, 1);
3824
3825 for (av = dim->attr->first_value; av; av = av->next)
3826 if (GET_CODE (av->value) == CONST_STRING)
3827 {
3828 exp = attr_eq (dim->attr->name, XSTR (av->value, 0));
3829 if (MEM_VOLATILE_P (exp))
3830 continue;
3831
3832 link = rtx_alloc (EXPR_LIST);
3833 XEXP (link, 0) = exp;
3834 XEXP (link, 1) = 0;
3835 *prev = link;
3836 prev = &XEXP (link, 1);
3837 }
3838 dim->num_values = nalt;
3839 }
3840 else
3841 {
3842 rtx orexp = false_rtx;
3843
3844 /* Very few values are used, so compute a mutually exclusive
3845 expression. (We could do this for numeric values if that becomes
3846 important.) */
3847 prev = &dim->values;
3848 for (link = dim->values; link; link = *prev)
3849 {
3850 orexp = insert_right_side (IOR, orexp, XEXP (link, 0), -2, -2);
3851 prev = &XEXP (link, 1);
3852 }
3853 link = rtx_alloc (EXPR_LIST);
3854 XEXP (link, 0) = attr_rtx (NOT, orexp);
3855 XEXP (link, 1) = 0;
3856 *prev = link;
3857 dim->num_values++;
3858 }
3859 return dim->num_values;
3860 }
3861
3862 /* Increment the current value for the NDIM-dimensional attribute space SPACE
3863 and return FALSE if the increment overflowed. */
3864
3865 static int
3866 increment_current_value (space, ndim)
3867 struct dimension *space;
3868 int ndim;
3869 {
3870 int i;
3871
3872 for (i = ndim - 1; i >= 0; i--)
3873 {
3874 if ((space[i].current_value = XEXP (space[i].current_value, 1)) == 0)
3875 space[i].current_value = space[i].values;
3876 else
3877 return 1;
3878 }
3879 return 0;
3880 }
3881
3882 /* Construct an expression corresponding to the current value for the
3883 NDIM-dimensional attribute space SPACE. */
3884
3885 static rtx
3886 test_for_current_value (space, ndim)
3887 struct dimension *space;
3888 int ndim;
3889 {
3890 int i;
3891 rtx exp = true_rtx;
3892
3893 for (i = 0; i < ndim; i++)
3894 exp = insert_right_side (AND, exp, XEXP (space[i].current_value, 0),
3895 -2, -2);
3896
3897 return exp;
3898 }
3899
3900 /* Given the current value of the NDIM-dimensional attribute space SPACE,
3901 set the corresponding EQ_ATTR expressions to that value and reduce
3902 the expression EXP as much as possible. On input [and output], all
3903 known EQ_ATTR expressions are set to FALSE. */
3904
3905 static rtx
3906 simplify_with_current_value (exp, space, ndim)
3907 rtx exp;
3908 struct dimension *space;
3909 int ndim;
3910 {
3911 int i;
3912 rtx x;
3913
3914 /* Mark each current value as TRUE. */
3915 for (i = 0; i < ndim; i++)
3916 {
3917 x = XEXP (space[i].current_value, 0);
3918 if (GET_CODE (x) == EQ_ATTR)
3919 MEM_VOLATILE_P (x) = 0;
3920 }
3921
3922 exp = simplify_with_current_value_aux (exp);
3923
3924 /* Change each current value back to FALSE. */
3925 for (i = 0; i < ndim; i++)
3926 {
3927 x = XEXP (space[i].current_value, 0);
3928 if (GET_CODE (x) == EQ_ATTR)
3929 MEM_VOLATILE_P (x) = 1;
3930 }
3931
3932 return exp;
3933 }
3934
3935 /* Reduce the expression EXP based on the MEM_VOLATILE_P settings of
3936 all EQ_ATTR expressions. */
3937
3938 static rtx
3939 simplify_with_current_value_aux (exp)
3940 rtx exp;
3941 {
3942 register int i;
3943 rtx cond;
3944
3945 switch (GET_CODE (exp))
3946 {
3947 case EQ_ATTR:
3948 if (MEM_VOLATILE_P (exp))
3949 return false_rtx;
3950 else
3951 return true_rtx;
3952 case CONST_STRING:
3953 case CONST_INT:
3954 return exp;
3955
3956 case IF_THEN_ELSE:
3957 cond = simplify_with_current_value_aux (XEXP (exp, 0));
3958 if (cond == true_rtx)
3959 return simplify_with_current_value_aux (XEXP (exp, 1));
3960 else if (cond == false_rtx)
3961 return simplify_with_current_value_aux (XEXP (exp, 2));
3962 else
3963 return attr_rtx (IF_THEN_ELSE, cond,
3964 simplify_with_current_value_aux (XEXP (exp, 1)),
3965 simplify_with_current_value_aux (XEXP (exp, 2)));
3966
3967 case IOR:
3968 cond = simplify_with_current_value_aux (XEXP (exp, 1));
3969 if (cond == true_rtx)
3970 return cond;
3971 else if (cond == false_rtx)
3972 return simplify_with_current_value_aux (XEXP (exp, 0));
3973 else
3974 return attr_rtx (IOR, cond,
3975 simplify_with_current_value_aux (XEXP (exp, 0)));
3976
3977 case AND:
3978 cond = simplify_with_current_value_aux (XEXP (exp, 1));
3979 if (cond == true_rtx)
3980 return simplify_with_current_value_aux (XEXP (exp, 0));
3981 else if (cond == false_rtx)
3982 return cond;
3983 else
3984 return attr_rtx (AND, cond,
3985 simplify_with_current_value_aux (XEXP (exp, 0)));
3986
3987 case NOT:
3988 cond = simplify_with_current_value_aux (XEXP (exp, 0));
3989 if (cond == true_rtx)
3990 return false_rtx;
3991 else if (cond == false_rtx)
3992 return true_rtx;
3993 else
3994 return attr_rtx (NOT, cond);
3995
3996 case COND:
3997 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3998 {
3999 cond = simplify_with_current_value_aux (XVECEXP (exp, 0, i));
4000 if (cond == true_rtx)
4001 return simplify_with_current_value_aux (XVECEXP (exp, 0, i + 1));
4002 else if (cond == false_rtx)
4003 continue;
4004 else
4005 abort (); /* With all EQ_ATTR's of known value, a case should
4006 have been selected. */
4007 }
4008 return simplify_with_current_value_aux (XEXP (exp, 1));
4009
4010 default:
4011 abort ();
4012 }
4013 }
4014 \f
4015 /* Clear the MEM_IN_STRUCT_P flag in EXP and its subexpressions. */
4016
4017 static void
4018 clear_struct_flag (x)
4019 rtx x;
4020 {
4021 register int i;
4022 register int j;
4023 register enum rtx_code code;
4024 register const char *fmt;
4025
4026 MEM_IN_STRUCT_P (x) = 0;
4027 if (RTX_UNCHANGING_P (x))
4028 return;
4029
4030 code = GET_CODE (x);
4031
4032 switch (code)
4033 {
4034 case REG:
4035 case QUEUED:
4036 case CONST_INT:
4037 case CONST_DOUBLE:
4038 case SYMBOL_REF:
4039 case CODE_LABEL:
4040 case PC:
4041 case CC0:
4042 case EQ_ATTR:
4043 case ATTR_FLAG:
4044 return;
4045
4046 default:
4047 break;
4048 }
4049
4050 /* Compare the elements. If any pair of corresponding elements
4051 fail to match, return 0 for the whole things. */
4052
4053 fmt = GET_RTX_FORMAT (code);
4054 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
4055 {
4056 switch (fmt[i])
4057 {
4058 case 'V':
4059 case 'E':
4060 for (j = 0; j < XVECLEN (x, i); j++)
4061 clear_struct_flag (XVECEXP (x, i, j));
4062 break;
4063
4064 case 'e':
4065 clear_struct_flag (XEXP (x, i));
4066 break;
4067 }
4068 }
4069 }
4070
4071 /* Return the number of RTX objects making up the expression X.
4072 But if we count more than MAX objects, stop counting. */
4073
4074 static int
4075 count_sub_rtxs (x, max)
4076 rtx x;
4077 int max;
4078 {
4079 register int i;
4080 register int j;
4081 register enum rtx_code code;
4082 register const char *fmt;
4083 int total = 0;
4084
4085 code = GET_CODE (x);
4086
4087 switch (code)
4088 {
4089 case REG:
4090 case QUEUED:
4091 case CONST_INT:
4092 case CONST_DOUBLE:
4093 case SYMBOL_REF:
4094 case CODE_LABEL:
4095 case PC:
4096 case CC0:
4097 case EQ_ATTR:
4098 case ATTR_FLAG:
4099 return 1;
4100
4101 default:
4102 break;
4103 }
4104
4105 /* Compare the elements. If any pair of corresponding elements
4106 fail to match, return 0 for the whole things. */
4107
4108 fmt = GET_RTX_FORMAT (code);
4109 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
4110 {
4111 if (total >= max)
4112 return total;
4113
4114 switch (fmt[i])
4115 {
4116 case 'V':
4117 case 'E':
4118 for (j = 0; j < XVECLEN (x, i); j++)
4119 total += count_sub_rtxs (XVECEXP (x, i, j), max);
4120 break;
4121
4122 case 'e':
4123 total += count_sub_rtxs (XEXP (x, i), max);
4124 break;
4125 }
4126 }
4127 return total;
4128
4129 }
4130 \f
4131 /* Create table entries for DEFINE_ATTR. */
4132
4133 static void
4134 gen_attr (exp)
4135 rtx exp;
4136 {
4137 struct attr_desc *attr;
4138 struct attr_value *av;
4139 char *name_ptr;
4140 char *p;
4141
4142 /* Make a new attribute structure. Check for duplicate by looking at
4143 attr->default_val, since it is initialized by this routine. */
4144 attr = find_attr (XSTR (exp, 0), 1);
4145 if (attr->default_val)
4146 fatal ("Duplicate definition for `%s' attribute", attr->name);
4147
4148 if (*XSTR (exp, 1) == '\0')
4149 attr->is_numeric = 1;
4150 else
4151 {
4152 name_ptr = XSTR (exp, 1);
4153 while ((p = next_comma_elt (&name_ptr)) != NULL)
4154 {
4155 av = (struct attr_value *) oballoc (sizeof (struct attr_value));
4156 av->value = attr_rtx (CONST_STRING, p);
4157 av->next = attr->first_value;
4158 attr->first_value = av;
4159 av->first_insn = NULL;
4160 av->num_insns = 0;
4161 av->has_asm_insn = 0;
4162 }
4163 }
4164
4165 if (GET_CODE (XEXP (exp, 2)) == CONST)
4166 {
4167 attr->is_const = 1;
4168 if (attr->is_numeric)
4169 fatal ("Constant attributes may not take numeric values");
4170 /* Get rid of the CONST node. It is allowed only at top-level. */
4171 XEXP (exp, 2) = XEXP (XEXP (exp, 2), 0);
4172 }
4173
4174 if (! strcmp (attr->name, "length") && ! attr->is_numeric)
4175 fatal ("`length' attribute must take numeric values");
4176
4177 /* Set up the default value. */
4178 XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
4179 attr->default_val = get_attr_value (XEXP (exp, 2), attr, -2);
4180 }
4181 \f
4182 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
4183 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
4184 number of alternatives as this should be checked elsewhere. */
4185
4186 static int
4187 count_alternatives (exp)
4188 rtx exp;
4189 {
4190 int i, j, n;
4191 const char *fmt;
4192
4193 if (GET_CODE (exp) == MATCH_OPERAND)
4194 return n_comma_elts (XSTR (exp, 2));
4195
4196 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
4197 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
4198 switch (*fmt++)
4199 {
4200 case 'e':
4201 case 'u':
4202 n = count_alternatives (XEXP (exp, i));
4203 if (n)
4204 return n;
4205 break;
4206
4207 case 'E':
4208 case 'V':
4209 if (XVEC (exp, i) != NULL)
4210 for (j = 0; j < XVECLEN (exp, i); j++)
4211 {
4212 n = count_alternatives (XVECEXP (exp, i, j));
4213 if (n)
4214 return n;
4215 }
4216 }
4217
4218 return 0;
4219 }
4220 \f
4221 /* Returns non-zero if the given expression contains an EQ_ATTR with the
4222 `alternative' attribute. */
4223
4224 static int
4225 compares_alternatives_p (exp)
4226 rtx exp;
4227 {
4228 int i, j;
4229 const char *fmt;
4230
4231 if (GET_CODE (exp) == EQ_ATTR && XSTR (exp, 0) == alternative_name)
4232 return 1;
4233
4234 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
4235 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
4236 switch (*fmt++)
4237 {
4238 case 'e':
4239 case 'u':
4240 if (compares_alternatives_p (XEXP (exp, i)))
4241 return 1;
4242 break;
4243
4244 case 'E':
4245 for (j = 0; j < XVECLEN (exp, i); j++)
4246 if (compares_alternatives_p (XVECEXP (exp, i, j)))
4247 return 1;
4248 break;
4249 }
4250
4251 return 0;
4252 }
4253 \f
4254 /* Returns non-zero is INNER is contained in EXP. */
4255
4256 static int
4257 contained_in_p (inner, exp)
4258 rtx inner;
4259 rtx exp;
4260 {
4261 int i, j;
4262 const char *fmt;
4263
4264 if (rtx_equal_p (inner, exp))
4265 return 1;
4266
4267 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
4268 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
4269 switch (*fmt++)
4270 {
4271 case 'e':
4272 case 'u':
4273 if (contained_in_p (inner, XEXP (exp, i)))
4274 return 1;
4275 break;
4276
4277 case 'E':
4278 for (j = 0; j < XVECLEN (exp, i); j++)
4279 if (contained_in_p (inner, XVECEXP (exp, i, j)))
4280 return 1;
4281 break;
4282 }
4283
4284 return 0;
4285 }
4286 \f
4287 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
4288
4289 static void
4290 gen_insn (exp)
4291 rtx exp;
4292 {
4293 struct insn_def *id;
4294
4295 id = (struct insn_def *) oballoc (sizeof (struct insn_def));
4296 id->next = defs;
4297 defs = id;
4298 id->def = exp;
4299
4300 switch (GET_CODE (exp))
4301 {
4302 case DEFINE_INSN:
4303 id->insn_code = insn_code_number++;
4304 id->insn_index = insn_index_number++;
4305 id->num_alternatives = count_alternatives (exp);
4306 if (id->num_alternatives == 0)
4307 id->num_alternatives = 1;
4308 id->vec_idx = 4;
4309 break;
4310
4311 case DEFINE_PEEPHOLE:
4312 id->insn_code = insn_code_number++;
4313 id->insn_index = insn_index_number++;
4314 id->num_alternatives = count_alternatives (exp);
4315 if (id->num_alternatives == 0)
4316 id->num_alternatives = 1;
4317 id->vec_idx = 3;
4318 break;
4319
4320 case DEFINE_ASM_ATTRIBUTES:
4321 id->insn_code = -1;
4322 id->insn_index = -1;
4323 id->num_alternatives = 1;
4324 id->vec_idx = 0;
4325 got_define_asm_attributes = 1;
4326 break;
4327
4328 default:
4329 abort ();
4330 }
4331 }
4332 \f
4333 /* Process a DEFINE_DELAY. Validate the vector length, check if annul
4334 true or annul false is specified, and make a `struct delay_desc'. */
4335
4336 static void
4337 gen_delay (def)
4338 rtx def;
4339 {
4340 struct delay_desc *delay;
4341 int i;
4342
4343 if (XVECLEN (def, 1) % 3 != 0)
4344 fatal ("Number of elements in DEFINE_DELAY must be multiple of three.");
4345
4346 for (i = 0; i < XVECLEN (def, 1); i += 3)
4347 {
4348 if (XVECEXP (def, 1, i + 1))
4349 have_annul_true = 1;
4350 if (XVECEXP (def, 1, i + 2))
4351 have_annul_false = 1;
4352 }
4353
4354 delay = (struct delay_desc *) oballoc (sizeof (struct delay_desc));
4355 delay->def = def;
4356 delay->num = ++num_delays;
4357 delay->next = delays;
4358 delays = delay;
4359 }
4360 \f
4361 /* Process a DEFINE_FUNCTION_UNIT.
4362
4363 This gives information about a function unit contained in the CPU.
4364 We fill in a `struct function_unit_op' and a `struct function_unit'
4365 with information used later by `expand_unit'. */
4366
4367 static void
4368 gen_unit (def)
4369 rtx def;
4370 {
4371 struct function_unit *unit;
4372 struct function_unit_op *op;
4373 char *name = XSTR (def, 0);
4374 int multiplicity = XINT (def, 1);
4375 int simultaneity = XINT (def, 2);
4376 rtx condexp = XEXP (def, 3);
4377 int ready_cost = MAX (XINT (def, 4), 1);
4378 int issue_delay = MAX (XINT (def, 5), 1);
4379
4380 /* See if we have already seen this function unit. If so, check that
4381 the multiplicity and simultaneity values are the same. If not, make
4382 a structure for this function unit. */
4383 for (unit = units; unit; unit = unit->next)
4384 if (! strcmp (unit->name, name))
4385 {
4386 if (unit->multiplicity != multiplicity
4387 || unit->simultaneity != simultaneity)
4388 fatal ("Differing specifications given for `%s' function unit.",
4389 unit->name);
4390 break;
4391 }
4392
4393 if (unit == 0)
4394 {
4395 unit = (struct function_unit *) oballoc (sizeof (struct function_unit));
4396 unit->name = name;
4397 unit->multiplicity = multiplicity;
4398 unit->simultaneity = simultaneity;
4399 unit->issue_delay.min = unit->issue_delay.max = issue_delay;
4400 unit->num = num_units++;
4401 unit->num_opclasses = 0;
4402 unit->condexp = false_rtx;
4403 unit->ops = 0;
4404 unit->next = units;
4405 units = unit;
4406 }
4407
4408 /* Make a new operation class structure entry and initialize it. */
4409 op = (struct function_unit_op *) oballoc (sizeof (struct function_unit_op));
4410 op->condexp = condexp;
4411 op->num = unit->num_opclasses++;
4412 op->ready = ready_cost;
4413 op->issue_delay = issue_delay;
4414 op->next = unit->ops;
4415 unit->ops = op;
4416 num_unit_opclasses++;
4417
4418 /* Set our issue expression based on whether or not an optional conflict
4419 vector was specified. */
4420 if (XVEC (def, 6))
4421 {
4422 /* Compute the IOR of all the specified expressions. */
4423 rtx orexp = false_rtx;
4424 int i;
4425
4426 for (i = 0; i < XVECLEN (def, 6); i++)
4427 orexp = insert_right_side (IOR, orexp, XVECEXP (def, 6, i), -2, -2);
4428
4429 op->conflict_exp = orexp;
4430 extend_range (&unit->issue_delay, 1, issue_delay);
4431 }
4432 else
4433 {
4434 op->conflict_exp = true_rtx;
4435 extend_range (&unit->issue_delay, issue_delay, issue_delay);
4436 }
4437
4438 /* Merge our conditional into that of the function unit so we can determine
4439 which insns are used by the function unit. */
4440 unit->condexp = insert_right_side (IOR, unit->condexp, op->condexp, -2, -2);
4441 }
4442 \f
4443 /* Given a piece of RTX, print a C expression to test its truth value.
4444 We use AND and IOR both for logical and bit-wise operations, so
4445 interpret them as logical unless they are inside a comparison expression.
4446 The first bit of FLAGS will be non-zero in that case.
4447
4448 Set the second bit of FLAGS to make references to attribute values use
4449 a cached local variable instead of calling a function. */
4450
4451 static void
4452 write_test_expr (exp, flags)
4453 rtx exp;
4454 int flags;
4455 {
4456 int comparison_operator = 0;
4457 RTX_CODE code;
4458 struct attr_desc *attr;
4459
4460 /* In order not to worry about operator precedence, surround our part of
4461 the expression with parentheses. */
4462
4463 printf ("(");
4464 code = GET_CODE (exp);
4465 switch (code)
4466 {
4467 /* Binary operators. */
4468 case EQ: case NE:
4469 case GE: case GT: case GEU: case GTU:
4470 case LE: case LT: case LEU: case LTU:
4471 comparison_operator = 1;
4472
4473 case PLUS: case MINUS: case MULT: case DIV: case MOD:
4474 case AND: case IOR: case XOR:
4475 case ASHIFT: case LSHIFTRT: case ASHIFTRT:
4476 write_test_expr (XEXP (exp, 0), flags | comparison_operator);
4477 switch (code)
4478 {
4479 case EQ:
4480 printf (" == ");
4481 break;
4482 case NE:
4483 printf (" != ");
4484 break;
4485 case GE:
4486 printf (" >= ");
4487 break;
4488 case GT:
4489 printf (" > ");
4490 break;
4491 case GEU:
4492 printf (" >= (unsigned) ");
4493 break;
4494 case GTU:
4495 printf (" > (unsigned) ");
4496 break;
4497 case LE:
4498 printf (" <= ");
4499 break;
4500 case LT:
4501 printf (" < ");
4502 break;
4503 case LEU:
4504 printf (" <= (unsigned) ");
4505 break;
4506 case LTU:
4507 printf (" < (unsigned) ");
4508 break;
4509 case PLUS:
4510 printf (" + ");
4511 break;
4512 case MINUS:
4513 printf (" - ");
4514 break;
4515 case MULT:
4516 printf (" * ");
4517 break;
4518 case DIV:
4519 printf (" / ");
4520 break;
4521 case MOD:
4522 printf (" %% ");
4523 break;
4524 case AND:
4525 if (flags & 1)
4526 printf (" & ");
4527 else
4528 printf (" && ");
4529 break;
4530 case IOR:
4531 if (flags & 1)
4532 printf (" | ");
4533 else
4534 printf (" || ");
4535 break;
4536 case XOR:
4537 printf (" ^ ");
4538 break;
4539 case ASHIFT:
4540 printf (" << ");
4541 break;
4542 case LSHIFTRT:
4543 case ASHIFTRT:
4544 printf (" >> ");
4545 break;
4546 default:
4547 abort ();
4548 }
4549
4550 write_test_expr (XEXP (exp, 1), flags | comparison_operator);
4551 break;
4552
4553 case NOT:
4554 /* Special-case (not (eq_attrq "alternative" "x")) */
4555 if (! (flags & 1) && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
4556 && XSTR (XEXP (exp, 0), 0) == alternative_name)
4557 {
4558 printf ("which_alternative != %s", XSTR (XEXP (exp, 0), 1));
4559 break;
4560 }
4561
4562 /* Otherwise, fall through to normal unary operator. */
4563
4564 /* Unary operators. */
4565 case ABS: case NEG:
4566 switch (code)
4567 {
4568 case NOT:
4569 if (flags & 1)
4570 printf ("~ ");
4571 else
4572 printf ("! ");
4573 break;
4574 case ABS:
4575 printf ("abs ");
4576 break;
4577 case NEG:
4578 printf ("-");
4579 break;
4580 default:
4581 abort ();
4582 }
4583
4584 write_test_expr (XEXP (exp, 0), flags);
4585 break;
4586
4587 /* Comparison test of an attribute with a value. Most of these will
4588 have been removed by optimization. Handle "alternative"
4589 specially and give error if EQ_ATTR present inside a comparison. */
4590 case EQ_ATTR:
4591 if (flags & 1)
4592 fatal ("EQ_ATTR not valid inside comparison");
4593
4594 if (XSTR (exp, 0) == alternative_name)
4595 {
4596 printf ("which_alternative == %s", XSTR (exp, 1));
4597 break;
4598 }
4599
4600 attr = find_attr (XSTR (exp, 0), 0);
4601 if (! attr) abort ();
4602
4603 /* Now is the time to expand the value of a constant attribute. */
4604 if (attr->is_const)
4605 {
4606 write_test_expr (evaluate_eq_attr (exp, attr->default_val->value,
4607 -2, -2),
4608 flags);
4609 }
4610 else
4611 {
4612 if (flags & 2)
4613 printf ("attr_%s", attr->name);
4614 else
4615 printf ("get_attr_%s (insn)", attr->name);
4616 printf (" == ");
4617 write_attr_valueq (attr, XSTR (exp, 1));
4618 }
4619 break;
4620
4621 /* Comparison test of flags for define_delays. */
4622 case ATTR_FLAG:
4623 if (flags & 1)
4624 fatal ("ATTR_FLAG not valid inside comparison");
4625 printf ("(flags & ATTR_FLAG_%s) != 0", XSTR (exp, 0));
4626 break;
4627
4628 /* See if an operand matches a predicate. */
4629 case MATCH_OPERAND:
4630 /* If only a mode is given, just ensure the mode matches the operand.
4631 If neither a mode nor predicate is given, error. */
4632 if (XSTR (exp, 1) == NULL || *XSTR (exp, 1) == '\0')
4633 {
4634 if (GET_MODE (exp) == VOIDmode)
4635 fatal ("Null MATCH_OPERAND specified as test");
4636 else
4637 printf ("GET_MODE (operands[%d]) == %smode",
4638 XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
4639 }
4640 else
4641 printf ("%s (operands[%d], %smode)",
4642 XSTR (exp, 1), XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
4643 break;
4644
4645 case MATCH_INSN:
4646 printf ("%s (insn)", XSTR (exp, 0));
4647 break;
4648
4649 /* Constant integer. */
4650 case CONST_INT:
4651 printf (HOST_WIDE_INT_PRINT_DEC, XWINT (exp, 0));
4652 break;
4653
4654 /* A random C expression. */
4655 case SYMBOL_REF:
4656 printf ("%s", XSTR (exp, 0));
4657 break;
4658
4659 /* The address of the branch target. */
4660 case MATCH_DUP:
4661 printf ("insn_addresses[INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])]",
4662 XINT (exp, 0), XINT (exp, 0), XINT (exp, 0));
4663 break;
4664
4665 case PC:
4666 /* The address of the current insn. We implement this actually as the
4667 address of the current insn for backward branches, but the last
4668 address of the next insn for forward branches, and both with
4669 adjustments that account for the worst-case possible stretching of
4670 intervening alignments between this insn and its destination. */
4671 printf("insn_current_reference_address (insn)");
4672 break;
4673
4674 case CONST_STRING:
4675 printf ("%s", XSTR (exp, 0));
4676 break;
4677
4678 case IF_THEN_ELSE:
4679 write_test_expr (XEXP (exp, 0), flags & 2);
4680 printf (" ? ");
4681 write_test_expr (XEXP (exp, 1), flags | 1);
4682 printf (" : ");
4683 write_test_expr (XEXP (exp, 2), flags | 1);
4684 break;
4685
4686 default:
4687 fatal ("bad RTX code `%s' in attribute calculation\n",
4688 GET_RTX_NAME (code));
4689 }
4690
4691 printf (")");
4692 }
4693 \f
4694 /* Given an attribute value, return the maximum CONST_STRING argument
4695 encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */
4696
4697 static int
4698 max_attr_value (exp, unknownp)
4699 rtx exp;
4700 int *unknownp;
4701 {
4702 int current_max;
4703 int i, n;
4704
4705 switch (GET_CODE (exp))
4706 {
4707 case CONST_STRING:
4708 current_max = atoi (XSTR (exp, 0));
4709 break;
4710
4711 case COND:
4712 current_max = max_attr_value (XEXP (exp, 1), unknownp);
4713 for (i = 0; i < XVECLEN (exp, 0); i += 2)
4714 {
4715 n = max_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
4716 if (n > current_max)
4717 current_max = n;
4718 }
4719 break;
4720
4721 case IF_THEN_ELSE:
4722 current_max = max_attr_value (XEXP (exp, 1), unknownp);
4723 n = max_attr_value (XEXP (exp, 2), unknownp);
4724 if (n > current_max)
4725 current_max = n;
4726 break;
4727
4728 default:
4729 *unknownp = 1;
4730 current_max = INT_MAX;
4731 break;
4732 }
4733
4734 return current_max;
4735 }
4736
4737 /* Given an attribute value, return the result of ORing together all
4738 CONST_STRING arguments encountered. Set *UNKNOWNP and return -1
4739 if the numeric value is not known. */
4740
4741 static int
4742 or_attr_value (exp, unknownp)
4743 rtx exp;
4744 int *unknownp;
4745 {
4746 int current_or;
4747 int i;
4748
4749 switch (GET_CODE (exp))
4750 {
4751 case CONST_STRING:
4752 current_or = atoi (XSTR (exp, 0));
4753 break;
4754
4755 case COND:
4756 current_or = or_attr_value (XEXP (exp, 1), unknownp);
4757 for (i = 0; i < XVECLEN (exp, 0); i += 2)
4758 current_or |= or_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
4759 break;
4760
4761 case IF_THEN_ELSE:
4762 current_or = or_attr_value (XEXP (exp, 1), unknownp);
4763 current_or |= or_attr_value (XEXP (exp, 2), unknownp);
4764 break;
4765
4766 default:
4767 *unknownp = 1;
4768 current_or = -1;
4769 break;
4770 }
4771
4772 return current_or;
4773 }
4774 \f
4775 /* Scan an attribute value, possibly a conditional, and record what actions
4776 will be required to do any conditional tests in it.
4777
4778 Specifically, set
4779 `must_extract' if we need to extract the insn operands
4780 `must_constrain' if we must compute `which_alternative'
4781 `address_used' if an address expression was used
4782 `length_used' if an (eq_attr "length" ...) was used
4783 */
4784
4785 static void
4786 walk_attr_value (exp)
4787 rtx exp;
4788 {
4789 register int i, j;
4790 register const char *fmt;
4791 RTX_CODE code;
4792
4793 if (exp == NULL)
4794 return;
4795
4796 code = GET_CODE (exp);
4797 switch (code)
4798 {
4799 case SYMBOL_REF:
4800 if (! RTX_UNCHANGING_P (exp))
4801 /* Since this is an arbitrary expression, it can look at anything.
4802 However, constant expressions do not depend on any particular
4803 insn. */
4804 must_extract = must_constrain = 1;
4805 return;
4806
4807 case MATCH_OPERAND:
4808 must_extract = 1;
4809 return;
4810
4811 case EQ_ATTR:
4812 if (XSTR (exp, 0) == alternative_name)
4813 must_extract = must_constrain = 1;
4814 else if (strcmp (XSTR (exp, 0), "length") == 0)
4815 length_used = 1;
4816 return;
4817
4818 case MATCH_DUP:
4819 must_extract = 1;
4820 address_used = 1;
4821 return;
4822
4823 case PC:
4824 address_used = 1;
4825 return;
4826
4827 case ATTR_FLAG:
4828 return;
4829
4830 default:
4831 break;
4832 }
4833
4834 for (i = 0, fmt = GET_RTX_FORMAT (code); i < GET_RTX_LENGTH (code); i++)
4835 switch (*fmt++)
4836 {
4837 case 'e':
4838 case 'u':
4839 walk_attr_value (XEXP (exp, i));
4840 break;
4841
4842 case 'E':
4843 if (XVEC (exp, i) != NULL)
4844 for (j = 0; j < XVECLEN (exp, i); j++)
4845 walk_attr_value (XVECEXP (exp, i, j));
4846 break;
4847 }
4848 }
4849 \f
4850 /* Write out a function to obtain the attribute for a given INSN. */
4851
4852 static void
4853 write_attr_get (attr)
4854 struct attr_desc *attr;
4855 {
4856 struct attr_value *av, *common_av;
4857
4858 /* Find the most used attribute value. Handle that as the `default' of the
4859 switch we will generate. */
4860 common_av = find_most_used (attr);
4861
4862 /* Write out prototype of function. */
4863 if (!attr->is_numeric)
4864 printf ("extern enum attr_%s ", attr->name);
4865 else if (attr->unsigned_p)
4866 printf ("extern unsigned int ");
4867 else
4868 printf ("extern int ");
4869 /* If the attribute name starts with a star, the remainder is the name of
4870 the subroutine to use, instead of `get_attr_...'. */
4871 if (attr->name[0] == '*')
4872 printf ("%s PROTO ((rtx));\n", &attr->name[1]);
4873 else
4874 printf ("get_attr_%s PROTO ((%s));\n", attr->name,
4875 (attr->is_const ? "void" : "rtx"));
4876
4877 /* Write out start of function, then all values with explicit `case' lines,
4878 then a `default', then the value with the most uses. */
4879 if (!attr->is_numeric)
4880 printf ("enum attr_%s\n", attr->name);
4881 else if (attr->unsigned_p)
4882 printf ("unsigned int\n");
4883 else
4884 printf ("int\n");
4885
4886 /* If the attribute name starts with a star, the remainder is the name of
4887 the subroutine to use, instead of `get_attr_...'. */
4888 if (attr->name[0] == '*')
4889 printf ("%s (insn)\n", &attr->name[1]);
4890 else if (attr->is_const == 0)
4891 printf ("get_attr_%s (insn)\n", attr->name);
4892 else
4893 {
4894 printf ("get_attr_%s ()\n", attr->name);
4895 printf ("{\n");
4896
4897 for (av = attr->first_value; av; av = av->next)
4898 if (av->num_insns != 0)
4899 write_attr_set (attr, 2, av->value, "return", ";",
4900 true_rtx, av->first_insn->insn_code,
4901 av->first_insn->insn_index);
4902
4903 printf ("}\n\n");
4904 return;
4905 }
4906
4907 printf (" rtx insn;\n");
4908 printf ("{\n");
4909
4910 if (GET_CODE (common_av->value) == FFS)
4911 {
4912 rtx p = XEXP (common_av->value, 0);
4913
4914 /* No need to emit code to abort if the insn is unrecognized; the
4915 other get_attr_foo functions will do that when we call them. */
4916
4917 write_toplevel_expr (p);
4918
4919 printf ("\n if (accum && accum == (accum & -accum))\n");
4920 printf (" {\n");
4921 printf (" int i;\n");
4922 printf (" for (i = 0; accum >>= 1; ++i) continue;\n");
4923 printf (" accum = i;\n");
4924 printf (" }\n else\n");
4925 printf (" accum = ~accum;\n");
4926 printf (" return accum;\n}\n\n");
4927 }
4928 else
4929 {
4930 printf (" switch (recog_memoized (insn))\n");
4931 printf (" {\n");
4932
4933 for (av = attr->first_value; av; av = av->next)
4934 if (av != common_av)
4935 write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
4936
4937 write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
4938 printf (" }\n}\n\n");
4939 }
4940 }
4941 \f
4942 /* Given an AND tree of known true terms (because we are inside an `if' with
4943 that as the condition or are in an `else' clause) and an expression,
4944 replace any known true terms with TRUE. Use `simplify_and_tree' to do
4945 the bulk of the work. */
4946
4947 static rtx
4948 eliminate_known_true (known_true, exp, insn_code, insn_index)
4949 rtx known_true;
4950 rtx exp;
4951 int insn_code, insn_index;
4952 {
4953 rtx term;
4954
4955 known_true = SIMPLIFY_TEST_EXP (known_true, insn_code, insn_index);
4956
4957 if (GET_CODE (known_true) == AND)
4958 {
4959 exp = eliminate_known_true (XEXP (known_true, 0), exp,
4960 insn_code, insn_index);
4961 exp = eliminate_known_true (XEXP (known_true, 1), exp,
4962 insn_code, insn_index);
4963 }
4964 else
4965 {
4966 term = known_true;
4967 exp = simplify_and_tree (exp, &term, insn_code, insn_index);
4968 }
4969
4970 return exp;
4971 }
4972 \f
4973 /* Write out a series of tests and assignment statements to perform tests and
4974 sets of an attribute value. We are passed an indentation amount and prefix
4975 and suffix strings to write around each attribute value (e.g., "return"
4976 and ";"). */
4977
4978 static void
4979 write_attr_set (attr, indent, value, prefix, suffix, known_true,
4980 insn_code, insn_index)
4981 struct attr_desc *attr;
4982 int indent;
4983 rtx value;
4984 const char *prefix;
4985 const char *suffix;
4986 rtx known_true;
4987 int insn_code, insn_index;
4988 {
4989 if (GET_CODE (value) == COND)
4990 {
4991 /* Assume the default value will be the default of the COND unless we
4992 find an always true expression. */
4993 rtx default_val = XEXP (value, 1);
4994 rtx our_known_true = known_true;
4995 rtx newexp;
4996 int first_if = 1;
4997 int i;
4998
4999 for (i = 0; i < XVECLEN (value, 0); i += 2)
5000 {
5001 rtx testexp;
5002 rtx inner_true;
5003
5004 testexp = eliminate_known_true (our_known_true,
5005 XVECEXP (value, 0, i),
5006 insn_code, insn_index);
5007 newexp = attr_rtx (NOT, testexp);
5008 newexp = insert_right_side (AND, our_known_true, newexp,
5009 insn_code, insn_index);
5010
5011 /* If the test expression is always true or if the next `known_true'
5012 expression is always false, this is the last case, so break
5013 out and let this value be the `else' case. */
5014 if (testexp == true_rtx || newexp == false_rtx)
5015 {
5016 default_val = XVECEXP (value, 0, i + 1);
5017 break;
5018 }
5019
5020 /* Compute the expression to pass to our recursive call as being
5021 known true. */
5022 inner_true = insert_right_side (AND, our_known_true,
5023 testexp, insn_code, insn_index);
5024
5025 /* If this is always false, skip it. */
5026 if (inner_true == false_rtx)
5027 continue;
5028
5029 write_indent (indent);
5030 printf ("%sif ", first_if ? "" : "else ");
5031 first_if = 0;
5032 write_test_expr (testexp, 0);
5033 printf ("\n");
5034 write_indent (indent + 2);
5035 printf ("{\n");
5036
5037 write_attr_set (attr, indent + 4,
5038 XVECEXP (value, 0, i + 1), prefix, suffix,
5039 inner_true, insn_code, insn_index);
5040 write_indent (indent + 2);
5041 printf ("}\n");
5042 our_known_true = newexp;
5043 }
5044
5045 if (! first_if)
5046 {
5047 write_indent (indent);
5048 printf ("else\n");
5049 write_indent (indent + 2);
5050 printf ("{\n");
5051 }
5052
5053 write_attr_set (attr, first_if ? indent : indent + 4, default_val,
5054 prefix, suffix, our_known_true, insn_code, insn_index);
5055
5056 if (! first_if)
5057 {
5058 write_indent (indent + 2);
5059 printf ("}\n");
5060 }
5061 }
5062 else
5063 {
5064 write_indent (indent);
5065 printf ("%s ", prefix);
5066 write_attr_value (attr, value);
5067 printf ("%s\n", suffix);
5068 }
5069 }
5070 \f
5071 /* Write out the computation for one attribute value. */
5072
5073 static void
5074 write_attr_case (attr, av, write_case_lines, prefix, suffix, indent,
5075 known_true)
5076 struct attr_desc *attr;
5077 struct attr_value *av;
5078 int write_case_lines;
5079 const char *prefix, *suffix;
5080 int indent;
5081 rtx known_true;
5082 {
5083 struct insn_ent *ie;
5084
5085 if (av->num_insns == 0)
5086 return;
5087
5088 if (av->has_asm_insn)
5089 {
5090 write_indent (indent);
5091 printf ("case -1:\n");
5092 write_indent (indent + 2);
5093 printf ("if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
5094 write_indent (indent + 2);
5095 printf (" && asm_noperands (PATTERN (insn)) < 0)\n");
5096 write_indent (indent + 2);
5097 printf (" fatal_insn_not_found (insn);\n");
5098 }
5099
5100 if (write_case_lines)
5101 {
5102 for (ie = av->first_insn; ie; ie = ie->next)
5103 if (ie->insn_code != -1)
5104 {
5105 write_indent (indent);
5106 printf ("case %d:\n", ie->insn_code);
5107 }
5108 }
5109 else
5110 {
5111 write_indent (indent);
5112 printf ("default:\n");
5113 }
5114
5115 /* See what we have to do to output this value. */
5116 must_extract = must_constrain = address_used = 0;
5117 walk_attr_value (av->value);
5118
5119 if (must_extract)
5120 {
5121 write_indent (indent + 2);
5122 printf ("extract_insn (insn);\n");
5123 }
5124
5125 if (must_constrain)
5126 {
5127 #ifdef REGISTER_CONSTRAINTS
5128 write_indent (indent + 2);
5129 printf ("if (! constrain_operands (reload_completed))\n");
5130 write_indent (indent + 2);
5131 printf (" fatal_insn_not_found (insn);\n");
5132 #endif
5133 }
5134
5135 write_attr_set (attr, indent + 2, av->value, prefix, suffix,
5136 known_true, av->first_insn->insn_code,
5137 av->first_insn->insn_index);
5138
5139 if (strncmp (prefix, "return", 6))
5140 {
5141 write_indent (indent + 2);
5142 printf ("break;\n");
5143 }
5144 printf ("\n");
5145 }
5146 \f
5147 /* Search for uses of non-const attributes and write code to cache them. */
5148
5149 static int
5150 write_expr_attr_cache (p, attr)
5151 rtx p;
5152 struct attr_desc *attr;
5153 {
5154 const char *fmt;
5155 int i, ie, j, je;
5156
5157 if (GET_CODE (p) == EQ_ATTR)
5158 {
5159 if (XSTR (p, 0) != attr->name)
5160 return 0;
5161
5162 if (!attr->is_numeric)
5163 printf (" register enum attr_%s ", attr->name);
5164 else if (attr->unsigned_p)
5165 printf (" register unsigned int ");
5166 else
5167 printf (" register int ");
5168
5169 printf ("attr_%s = get_attr_%s (insn);\n", attr->name, attr->name);
5170 return 1;
5171 }
5172
5173 fmt = GET_RTX_FORMAT (GET_CODE (p));
5174 ie = GET_RTX_LENGTH (GET_CODE (p));
5175 for (i = 0; i < ie; i++)
5176 {
5177 switch (*fmt++)
5178 {
5179 case 'e':
5180 if (write_expr_attr_cache (XEXP (p, i), attr))
5181 return 1;
5182 break;
5183
5184 case 'E':
5185 je = XVECLEN (p, i);
5186 for (j = 0; j < je; ++j)
5187 if (write_expr_attr_cache (XVECEXP (p, i, j), attr))
5188 return 1;
5189 break;
5190 }
5191 }
5192
5193 return 0;
5194 }
5195
5196 /* Evaluate an expression at top level. A front end to write_test_expr,
5197 in which we cache attribute values and break up excessively large
5198 expressions to cater to older compilers. */
5199
5200 static void
5201 write_toplevel_expr (p)
5202 rtx p;
5203 {
5204 struct attr_desc *attr;
5205 int i;
5206
5207 for (i = 0; i < MAX_ATTRS_INDEX; ++i)
5208 for (attr = attrs[i]; attr ; attr = attr->next)
5209 if (!attr->is_const)
5210 write_expr_attr_cache (p, attr);
5211
5212 printf(" register unsigned long accum = 0;\n\n");
5213
5214 while (GET_CODE (p) == IOR)
5215 {
5216 rtx e;
5217 if (GET_CODE (XEXP (p, 0)) == IOR)
5218 e = XEXP (p, 1), p = XEXP (p, 0);
5219 else
5220 e = XEXP (p, 0), p = XEXP (p, 1);
5221
5222 printf (" accum |= ");
5223 write_test_expr (e, 3);
5224 printf (";\n");
5225 }
5226 printf (" accum |= ");
5227 write_test_expr (p, 3);
5228 printf (";\n");
5229 }
5230 \f
5231 /* Utilities to write names in various forms. */
5232
5233 static void
5234 write_unit_name (prefix, num, suffix)
5235 const char *prefix;
5236 int num;
5237 const char *suffix;
5238 {
5239 struct function_unit *unit;
5240
5241 for (unit = units; unit; unit = unit->next)
5242 if (unit->num == num)
5243 {
5244 printf ("%s%s%s", prefix, unit->name, suffix);
5245 return;
5246 }
5247
5248 printf ("%s<unknown>%s", prefix, suffix);
5249 }
5250
5251 static void
5252 write_attr_valueq (attr, s)
5253 struct attr_desc *attr;
5254 char *s;
5255 {
5256 if (attr->is_numeric)
5257 {
5258 int num = atoi (s);
5259
5260 printf ("%d", num);
5261
5262 /* Make the blockage range values and function units used values easier
5263 to read. */
5264 if (attr->func_units_p)
5265 {
5266 if (num == -1)
5267 printf (" /* units: none */");
5268 else if (num >= 0)
5269 write_unit_name (" /* units: ", num, " */");
5270 else
5271 {
5272 int i;
5273 const char *sep = " /* units: ";
5274 for (i = 0, num = ~num; num; i++, num >>= 1)
5275 if (num & 1)
5276 {
5277 write_unit_name (sep, i, (num == 1) ? " */" : "");
5278 sep = ", ";
5279 }
5280 }
5281 }
5282
5283 else if (attr->blockage_p)
5284 printf (" /* min %d, max %d */", num >> (HOST_BITS_PER_INT / 2),
5285 num & ((1 << (HOST_BITS_PER_INT / 2)) - 1));
5286
5287 else if (num > 9 || num < 0)
5288 printf (" /* 0x%x */", num);
5289 }
5290 else
5291 {
5292 write_upcase (attr->name);
5293 printf ("_");
5294 write_upcase (s);
5295 }
5296 }
5297
5298 static void
5299 write_attr_value (attr, value)
5300 struct attr_desc *attr;
5301 rtx value;
5302 {
5303 int op;
5304
5305 switch (GET_CODE (value))
5306 {
5307 case CONST_STRING:
5308 write_attr_valueq (attr, XSTR (value, 0));
5309 break;
5310
5311 case SYMBOL_REF:
5312 fputs (XSTR (value, 0), stdout);
5313 break;
5314
5315 case ATTR:
5316 {
5317 struct attr_desc *attr2 = find_attr (XSTR (value, 0), 0);
5318 printf ("get_attr_%s (%s)", attr2->name,
5319 (attr2->is_const ? "" : "insn"));
5320 }
5321 break;
5322
5323 case PLUS:
5324 op = '+';
5325 goto do_operator;
5326 case MINUS:
5327 op = '-';
5328 goto do_operator;
5329 case MULT:
5330 op = '*';
5331 goto do_operator;
5332 case DIV:
5333 op = '/';
5334 goto do_operator;
5335 case MOD:
5336 op = '%';
5337 goto do_operator;
5338
5339 do_operator:
5340 write_attr_value (attr, XEXP (value, 0));
5341 putchar (' ');
5342 putchar (op);
5343 putchar (' ');
5344 write_attr_value (attr, XEXP (value, 1));
5345 break;
5346
5347 default:
5348 abort ();
5349 }
5350 }
5351
5352 static void
5353 write_upcase (str)
5354 char *str;
5355 {
5356 while (*str)
5357 if (ISLOWER(*str))
5358 printf ("%c", toupper(*str++));
5359 else
5360 printf ("%c", *str++);
5361 }
5362
5363 static void
5364 write_indent (indent)
5365 int indent;
5366 {
5367 for (; indent > 8; indent -= 8)
5368 printf ("\t");
5369
5370 for (; indent; indent--)
5371 printf (" ");
5372 }
5373 \f
5374 /* Write a subroutine that is given an insn that requires a delay slot, a
5375 delay slot ordinal, and a candidate insn. It returns non-zero if the
5376 candidate can be placed in the specified delay slot of the insn.
5377
5378 We can write as many as three subroutines. `eligible_for_delay'
5379 handles normal delay slots, `eligible_for_annul_true' indicates that
5380 the specified insn can be annulled if the branch is true, and likewise
5381 for `eligible_for_annul_false'.
5382
5383 KIND is a string distinguishing these three cases ("delay", "annul_true",
5384 or "annul_false"). */
5385
5386 static void
5387 write_eligible_delay (kind)
5388 const char *kind;
5389 {
5390 struct delay_desc *delay;
5391 int max_slots;
5392 char str[50];
5393 struct attr_desc *attr;
5394 struct attr_value *av, *common_av;
5395 int i;
5396
5397 /* Compute the maximum number of delay slots required. We use the delay
5398 ordinal times this number plus one, plus the slot number as an index into
5399 the appropriate predicate to test. */
5400
5401 for (delay = delays, max_slots = 0; delay; delay = delay->next)
5402 if (XVECLEN (delay->def, 1) / 3 > max_slots)
5403 max_slots = XVECLEN (delay->def, 1) / 3;
5404
5405 /* Write function prelude. */
5406
5407 printf ("int\n");
5408 printf ("eligible_for_%s (delay_insn, slot, candidate_insn, flags)\n",
5409 kind);
5410 printf (" rtx delay_insn;\n");
5411 printf (" int slot;\n");
5412 printf (" rtx candidate_insn;\n");
5413 printf (" int flags ATTRIBUTE_UNUSED;\n");
5414 printf ("{\n");
5415 printf (" rtx insn;\n");
5416 printf ("\n");
5417 printf (" if (slot >= %d)\n", max_slots);
5418 printf (" abort ();\n");
5419 printf ("\n");
5420
5421 /* If more than one delay type, find out which type the delay insn is. */
5422
5423 if (num_delays > 1)
5424 {
5425 attr = find_attr ("*delay_type", 0);
5426 if (! attr) abort ();
5427 common_av = find_most_used (attr);
5428
5429 printf (" insn = delay_insn;\n");
5430 printf (" switch (recog_memoized (insn))\n");
5431 printf (" {\n");
5432
5433 sprintf (str, " * %d;\n break;", max_slots);
5434 for (av = attr->first_value; av; av = av->next)
5435 if (av != common_av)
5436 write_attr_case (attr, av, 1, "slot +=", str, 4, true_rtx);
5437
5438 write_attr_case (attr, common_av, 0, "slot +=", str, 4, true_rtx);
5439 printf (" }\n\n");
5440
5441 /* Ensure matched. Otherwise, shouldn't have been called. */
5442 printf (" if (slot < %d)\n", max_slots);
5443 printf (" abort ();\n\n");
5444 }
5445
5446 /* If just one type of delay slot, write simple switch. */
5447 if (num_delays == 1 && max_slots == 1)
5448 {
5449 printf (" insn = candidate_insn;\n");
5450 printf (" switch (recog_memoized (insn))\n");
5451 printf (" {\n");
5452
5453 attr = find_attr ("*delay_1_0", 0);
5454 if (! attr) abort ();
5455 common_av = find_most_used (attr);
5456
5457 for (av = attr->first_value; av; av = av->next)
5458 if (av != common_av)
5459 write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
5460
5461 write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
5462 printf (" }\n");
5463 }
5464
5465 else
5466 {
5467 /* Write a nested CASE. The first indicates which condition we need to
5468 test, and the inner CASE tests the condition. */
5469 printf (" insn = candidate_insn;\n");
5470 printf (" switch (slot)\n");
5471 printf (" {\n");
5472
5473 for (delay = delays; delay; delay = delay->next)
5474 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
5475 {
5476 printf (" case %d:\n",
5477 (i / 3) + (num_delays == 1 ? 0 : delay->num * max_slots));
5478 printf (" switch (recog_memoized (insn))\n");
5479 printf ("\t{\n");
5480
5481 sprintf (str, "*%s_%d_%d", kind, delay->num, i / 3);
5482 attr = find_attr (str, 0);
5483 if (! attr) abort ();
5484 common_av = find_most_used (attr);
5485
5486 for (av = attr->first_value; av; av = av->next)
5487 if (av != common_av)
5488 write_attr_case (attr, av, 1, "return", ";", 8, true_rtx);
5489
5490 write_attr_case (attr, common_av, 0, "return", ";", 8, true_rtx);
5491 printf (" }\n");
5492 }
5493
5494 printf (" default:\n");
5495 printf (" abort ();\n");
5496 printf (" }\n");
5497 }
5498
5499 printf ("}\n\n");
5500 }
5501 \f
5502 /* Write routines to compute conflict cost for function units. Then write a
5503 table describing the available function units. */
5504
5505 static void
5506 write_function_unit_info ()
5507 {
5508 struct function_unit *unit;
5509 int i;
5510
5511 /* Write out conflict routines for function units. Don't bother writing
5512 one if there is only one issue delay value. */
5513
5514 for (unit = units; unit; unit = unit->next)
5515 {
5516 if (unit->needs_blockage_function)
5517 write_complex_function (unit, "blockage", "block");
5518
5519 /* If the minimum and maximum conflict costs are the same, there
5520 is only one value, so we don't need a function. */
5521 if (! unit->needs_conflict_function)
5522 {
5523 unit->default_cost = make_numeric_value (unit->issue_delay.max);
5524 continue;
5525 }
5526
5527 /* The function first computes the case from the candidate insn. */
5528 unit->default_cost = make_numeric_value (0);
5529 write_complex_function (unit, "conflict_cost", "cost");
5530 }
5531
5532 /* Now that all functions have been written, write the table describing
5533 the function units. The name is included for documentation purposes
5534 only. */
5535
5536 printf ("struct function_unit_desc function_units[] = {\n");
5537
5538 /* Write out the descriptions in numeric order, but don't force that order
5539 on the list. Doing so increases the runtime of genattrtab.c. */
5540 for (i = 0; i < num_units; i++)
5541 {
5542 for (unit = units; unit; unit = unit->next)
5543 if (unit->num == i)
5544 break;
5545
5546 printf (" {\"%s\", %d, %d, %d, %s, %d, %s_unit_ready_cost, ",
5547 unit->name, 1 << unit->num, unit->multiplicity,
5548 unit->simultaneity, XSTR (unit->default_cost, 0),
5549 unit->issue_delay.max, unit->name);
5550
5551 if (unit->needs_conflict_function)
5552 printf ("%s_unit_conflict_cost, ", unit->name);
5553 else
5554 printf ("0, ");
5555
5556 printf ("%d, ", unit->max_blockage);
5557
5558 if (unit->needs_range_function)
5559 printf ("%s_unit_blockage_range, ", unit->name);
5560 else
5561 printf ("0, ");
5562
5563 if (unit->needs_blockage_function)
5564 printf ("%s_unit_blockage", unit->name);
5565 else
5566 printf ("0");
5567
5568 printf ("}, \n");
5569 }
5570
5571 printf ("};\n\n");
5572 }
5573
5574 static void
5575 write_complex_function (unit, name, connection)
5576 struct function_unit *unit;
5577 const char *name, *connection;
5578 {
5579 struct attr_desc *case_attr, *attr;
5580 struct attr_value *av, *common_av;
5581 rtx value;
5582 char *str;
5583 int using_case;
5584 int i;
5585
5586 printf ("static int %s_unit_%s PROTO ((rtx, rtx));\n", unit->name, name);
5587 printf ("static int\n");
5588 printf ("%s_unit_%s (executing_insn, candidate_insn)\n",
5589 unit->name, name);
5590 printf (" rtx executing_insn;\n");
5591 printf (" rtx candidate_insn;\n");
5592 printf ("{\n");
5593 printf (" rtx insn;\n");
5594 printf (" int casenum;\n\n");
5595 printf (" insn = executing_insn;\n");
5596 printf (" switch (recog_memoized (insn))\n");
5597 printf (" {\n");
5598
5599 /* Write the `switch' statement to get the case value. */
5600 str = (char *) alloca (strlen (unit->name) + strlen (name) + strlen (connection) + 10);
5601 sprintf (str, "*%s_cases", unit->name);
5602 case_attr = find_attr (str, 0);
5603 if (! case_attr) abort ();
5604 common_av = find_most_used (case_attr);
5605
5606 for (av = case_attr->first_value; av; av = av->next)
5607 if (av != common_av)
5608 write_attr_case (case_attr, av, 1,
5609 "casenum =", ";", 4, unit->condexp);
5610
5611 write_attr_case (case_attr, common_av, 0,
5612 "casenum =", ";", 4, unit->condexp);
5613 printf (" }\n\n");
5614
5615 /* Now write an outer switch statement on each case. Then write
5616 the tests on the executing function within each. */
5617 printf (" insn = candidate_insn;\n");
5618 printf (" switch (casenum)\n");
5619 printf (" {\n");
5620
5621 for (i = 0; i < unit->num_opclasses; i++)
5622 {
5623 /* Ensure using this case. */
5624 using_case = 0;
5625 for (av = case_attr->first_value; av; av = av->next)
5626 if (av->num_insns
5627 && contained_in_p (make_numeric_value (i), av->value))
5628 using_case = 1;
5629
5630 if (! using_case)
5631 continue;
5632
5633 printf (" case %d:\n", i);
5634 sprintf (str, "*%s_%s_%d", unit->name, connection, i);
5635 attr = find_attr (str, 0);
5636 if (! attr) abort ();
5637
5638 /* If single value, just write it. */
5639 value = find_single_value (attr);
5640 if (value)
5641 write_attr_set (attr, 6, value, "return", ";\n", true_rtx, -2, -2);
5642 else
5643 {
5644 common_av = find_most_used (attr);
5645 printf (" switch (recog_memoized (insn))\n");
5646 printf ("\t{\n");
5647
5648 for (av = attr->first_value; av; av = av->next)
5649 if (av != common_av)
5650 write_attr_case (attr, av, 1,
5651 "return", ";", 8, unit->condexp);
5652
5653 write_attr_case (attr, common_av, 0,
5654 "return", ";", 8, unit->condexp);
5655 printf (" }\n\n");
5656 }
5657 }
5658
5659 /* This default case should not be needed, but gcc's analysis is not
5660 good enough to realize that the default case is not needed for the
5661 second switch statement. */
5662 printf (" default:\n abort ();\n");
5663 printf (" }\n}\n\n");
5664 }
5665 \f
5666 /* This page contains miscellaneous utility routines. */
5667
5668 /* Given a string, return the number of comma-separated elements in it.
5669 Return 0 for the null string. */
5670
5671 static int
5672 n_comma_elts (s)
5673 char *s;
5674 {
5675 int n;
5676
5677 if (*s == '\0')
5678 return 0;
5679
5680 for (n = 1; *s; s++)
5681 if (*s == ',')
5682 n++;
5683
5684 return n;
5685 }
5686
5687 /* Given a pointer to a (char *), return a malloc'ed string containing the
5688 next comma-separated element. Advance the pointer to after the string
5689 scanned, or the end-of-string. Return NULL if at end of string. */
5690
5691 static char *
5692 next_comma_elt (pstr)
5693 char **pstr;
5694 {
5695 char *out_str;
5696 char *p;
5697
5698 if (**pstr == '\0')
5699 return NULL;
5700
5701 /* Find end of string to compute length. */
5702 for (p = *pstr; *p != ',' && *p != '\0'; p++)
5703 ;
5704
5705 out_str = attr_string (*pstr, p - *pstr);
5706 *pstr = p;
5707
5708 if (**pstr == ',')
5709 (*pstr)++;
5710
5711 return out_str;
5712 }
5713
5714 /* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
5715 is non-zero, build a new attribute, if one does not exist. */
5716
5717 static struct attr_desc *
5718 find_attr (name, create)
5719 const char *name;
5720 int create;
5721 {
5722 struct attr_desc *attr;
5723 int index;
5724
5725 /* Before we resort to using `strcmp', see if the string address matches
5726 anywhere. In most cases, it should have been canonicalized to do so. */
5727 if (name == alternative_name)
5728 return NULL;
5729
5730 index = name[0] & (MAX_ATTRS_INDEX - 1);
5731 for (attr = attrs[index]; attr; attr = attr->next)
5732 if (name == attr->name)
5733 return attr;
5734
5735 /* Otherwise, do it the slow way. */
5736 for (attr = attrs[index]; attr; attr = attr->next)
5737 if (name[0] == attr->name[0] && ! strcmp (name, attr->name))
5738 return attr;
5739
5740 if (! create)
5741 return NULL;
5742
5743 attr = (struct attr_desc *) oballoc (sizeof (struct attr_desc));
5744 attr->name = attr_string (name, strlen (name));
5745 attr->first_value = attr->default_val = NULL;
5746 attr->is_numeric = attr->negative_ok = attr->is_const = attr->is_special = 0;
5747 attr->next = attrs[index];
5748 attrs[index] = attr;
5749
5750 return attr;
5751 }
5752
5753 /* Create internal attribute with the given default value. */
5754
5755 static void
5756 make_internal_attr (name, value, special)
5757 const char *name;
5758 rtx value;
5759 int special;
5760 {
5761 struct attr_desc *attr;
5762
5763 attr = find_attr (name, 1);
5764 if (attr->default_val)
5765 abort ();
5766
5767 attr->is_numeric = 1;
5768 attr->is_const = 0;
5769 attr->is_special = (special & 1) != 0;
5770 attr->negative_ok = (special & 2) != 0;
5771 attr->unsigned_p = (special & 4) != 0;
5772 attr->func_units_p = (special & 8) != 0;
5773 attr->blockage_p = (special & 16) != 0;
5774 attr->default_val = get_attr_value (value, attr, -2);
5775 }
5776
5777 /* Find the most used value of an attribute. */
5778
5779 static struct attr_value *
5780 find_most_used (attr)
5781 struct attr_desc *attr;
5782 {
5783 struct attr_value *av;
5784 struct attr_value *most_used;
5785 int nuses;
5786
5787 most_used = NULL;
5788 nuses = -1;
5789
5790 for (av = attr->first_value; av; av = av->next)
5791 if (av->num_insns > nuses)
5792 nuses = av->num_insns, most_used = av;
5793
5794 return most_used;
5795 }
5796
5797 /* If an attribute only has a single value used, return it. Otherwise
5798 return NULL. */
5799
5800 static rtx
5801 find_single_value (attr)
5802 struct attr_desc *attr;
5803 {
5804 struct attr_value *av;
5805 rtx unique_value;
5806
5807 unique_value = NULL;
5808 for (av = attr->first_value; av; av = av->next)
5809 if (av->num_insns)
5810 {
5811 if (unique_value)
5812 return NULL;
5813 else
5814 unique_value = av->value;
5815 }
5816
5817 return unique_value;
5818 }
5819
5820 /* Return (attr_value "n") */
5821
5822 static rtx
5823 make_numeric_value (n)
5824 int n;
5825 {
5826 static rtx int_values[20];
5827 rtx exp;
5828 char *p;
5829
5830 if (n < 0)
5831 abort ();
5832
5833 if (n < 20 && int_values[n])
5834 return int_values[n];
5835
5836 p = attr_printf (MAX_DIGITS, "%d", n);
5837 exp = attr_rtx (CONST_STRING, p);
5838
5839 if (n < 20)
5840 int_values[n] = exp;
5841
5842 return exp;
5843 }
5844 \f
5845 static void
5846 extend_range (range, min, max)
5847 struct range *range;
5848 int min;
5849 int max;
5850 {
5851 if (range->min > min) range->min = min;
5852 if (range->max < max) range->max = max;
5853 }
5854
5855 PTR
5856 xrealloc (old, size)
5857 PTR old;
5858 size_t size;
5859 {
5860 register PTR ptr;
5861 if (old)
5862 ptr = (PTR) realloc (old, size);
5863 else
5864 ptr = (PTR) malloc (size);
5865 if (!ptr)
5866 fatal ("virtual memory exhausted");
5867 return ptr;
5868 }
5869
5870 PTR
5871 xmalloc (size)
5872 size_t size;
5873 {
5874 register PTR val = (PTR) malloc (size);
5875
5876 if (val == 0)
5877 fatal ("virtual memory exhausted");
5878 return val;
5879 }
5880
5881 static rtx
5882 copy_rtx_unchanging (orig)
5883 register rtx orig;
5884 {
5885 #if 0
5886 register rtx copy;
5887 register RTX_CODE code;
5888 #endif
5889
5890 if (RTX_UNCHANGING_P (orig) || MEM_IN_STRUCT_P (orig))
5891 return orig;
5892
5893 MEM_IN_STRUCT_P (orig) = 1;
5894 return orig;
5895
5896 #if 0
5897 code = GET_CODE (orig);
5898 switch (code)
5899 {
5900 case CONST_INT:
5901 case CONST_DOUBLE:
5902 case SYMBOL_REF:
5903 case CODE_LABEL:
5904 return orig;
5905
5906 default:
5907 break;
5908 }
5909
5910 copy = rtx_alloc (code);
5911 PUT_MODE (copy, GET_MODE (orig));
5912 RTX_UNCHANGING_P (copy) = 1;
5913
5914 bcopy ((char *) &XEXP (orig, 0), (char *) &XEXP (copy, 0),
5915 GET_RTX_LENGTH (GET_CODE (copy)) * sizeof (rtx));
5916 return copy;
5917 #endif
5918 }
5919
5920 /* Determine if an insn has a constant number of delay slots, i.e., the
5921 number of delay slots is not a function of the length of the insn. */
5922
5923 static void
5924 write_const_num_delay_slots ()
5925 {
5926 struct attr_desc *attr = find_attr ("*num_delay_slots", 0);
5927 struct attr_value *av;
5928 struct insn_ent *ie;
5929
5930 if (attr)
5931 {
5932 printf ("int\nconst_num_delay_slots (insn)\n");
5933 printf (" rtx insn;\n");
5934 printf ("{\n");
5935 printf (" switch (recog_memoized (insn))\n");
5936 printf (" {\n");
5937
5938 for (av = attr->first_value; av; av = av->next)
5939 {
5940 length_used = 0;
5941 walk_attr_value (av->value);
5942 if (length_used)
5943 {
5944 for (ie = av->first_insn; ie; ie = ie->next)
5945 if (ie->insn_code != -1)
5946 printf (" case %d:\n", ie->insn_code);
5947 printf (" return 0;\n");
5948 }
5949 }
5950
5951 printf (" default:\n");
5952 printf (" return 1;\n");
5953 printf (" }\n}\n\n");
5954 }
5955 }
5956
5957 \f
5958 int
5959 main (argc, argv)
5960 int argc;
5961 char **argv;
5962 {
5963 rtx desc;
5964 FILE *infile;
5965 register int c;
5966 struct attr_desc *attr;
5967 struct insn_def *id;
5968 rtx tem;
5969 int i;
5970
5971 progname = "genattrtab";
5972
5973 #if defined (RLIMIT_STACK) && defined (HAVE_GETRLIMIT) && defined (HAVE_SETRLIMIT)
5974 /* Get rid of any avoidable limit on stack size. */
5975 {
5976 struct rlimit rlim;
5977
5978 /* Set the stack limit huge so that alloca does not fail. */
5979 getrlimit (RLIMIT_STACK, &rlim);
5980 rlim.rlim_cur = rlim.rlim_max;
5981 setrlimit (RLIMIT_STACK, &rlim);
5982 }
5983 #endif
5984
5985 progname = "genattrtab";
5986 obstack_init (rtl_obstack);
5987 obstack_init (hash_obstack);
5988 obstack_init (temp_obstack);
5989
5990 if (argc <= 1)
5991 fatal ("No input file name.");
5992
5993 infile = fopen (argv[1], "r");
5994 if (infile == 0)
5995 {
5996 perror (argv[1]);
5997 exit (FATAL_EXIT_CODE);
5998 }
5999
6000 /* Set up true and false rtx's */
6001 true_rtx = rtx_alloc (CONST_INT);
6002 XWINT (true_rtx, 0) = 1;
6003 false_rtx = rtx_alloc (CONST_INT);
6004 XWINT (false_rtx, 0) = 0;
6005 RTX_UNCHANGING_P (true_rtx) = RTX_UNCHANGING_P (false_rtx) = 1;
6006 RTX_INTEGRATED_P (true_rtx) = RTX_INTEGRATED_P (false_rtx) = 1;
6007
6008 alternative_name = attr_string ("alternative", strlen ("alternative"));
6009
6010 printf ("/* Generated automatically by the program `genattrtab'\n\
6011 from the machine description file `md'. */\n\n");
6012
6013 /* Read the machine description. */
6014
6015 while (1)
6016 {
6017 c = read_skip_spaces (infile);
6018 if (c == EOF)
6019 break;
6020 ungetc (c, infile);
6021
6022 desc = read_rtx (infile);
6023 if (GET_CODE (desc) == DEFINE_INSN
6024 || GET_CODE (desc) == DEFINE_PEEPHOLE
6025 || GET_CODE (desc) == DEFINE_ASM_ATTRIBUTES)
6026 gen_insn (desc);
6027
6028 else if (GET_CODE (desc) == DEFINE_EXPAND)
6029 insn_code_number++, insn_index_number++;
6030
6031 else if (GET_CODE (desc) == DEFINE_SPLIT)
6032 insn_code_number++, insn_index_number++;
6033
6034 else if (GET_CODE (desc) == DEFINE_PEEPHOLE2)
6035 insn_code_number++, insn_index_number++;
6036
6037 else if (GET_CODE (desc) == DEFINE_ATTR)
6038 {
6039 gen_attr (desc);
6040 insn_index_number++;
6041 }
6042
6043 else if (GET_CODE (desc) == DEFINE_DELAY)
6044 {
6045 gen_delay (desc);
6046 insn_index_number++;
6047 }
6048
6049 else if (GET_CODE (desc) == DEFINE_FUNCTION_UNIT)
6050 {
6051 gen_unit (desc);
6052 insn_index_number++;
6053 }
6054 }
6055
6056 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
6057 if (! got_define_asm_attributes)
6058 {
6059 tem = rtx_alloc (DEFINE_ASM_ATTRIBUTES);
6060 XVEC (tem, 0) = rtvec_alloc (0);
6061 gen_insn (tem);
6062 }
6063
6064 /* Expand DEFINE_DELAY information into new attribute. */
6065 if (num_delays)
6066 expand_delays ();
6067
6068 /* Expand DEFINE_FUNCTION_UNIT information into new attributes. */
6069 if (num_units)
6070 expand_units ();
6071
6072 printf ("#include \"config.h\"\n");
6073 printf ("#include \"system.h\"\n");
6074 printf ("#include \"rtl.h\"\n");
6075 printf ("#include \"insn-config.h\"\n");
6076 printf ("#include \"recog.h\"\n");
6077 printf ("#include \"regs.h\"\n");
6078 printf ("#include \"real.h\"\n");
6079 printf ("#include \"output.h\"\n");
6080 printf ("#include \"insn-attr.h\"\n");
6081 printf ("#include \"toplev.h\"\n");
6082 printf ("\n");
6083 printf ("#define operands recog_data.operand\n\n");
6084
6085 /* Make `insn_alternatives'. */
6086 insn_alternatives = (int *) oballoc (insn_code_number * sizeof (int));
6087 for (id = defs; id; id = id->next)
6088 if (id->insn_code >= 0)
6089 insn_alternatives[id->insn_code] = (1 << id->num_alternatives) - 1;
6090
6091 /* Make `insn_n_alternatives'. */
6092 insn_n_alternatives = (int *) oballoc (insn_code_number * sizeof (int));
6093 for (id = defs; id; id = id->next)
6094 if (id->insn_code >= 0)
6095 insn_n_alternatives[id->insn_code] = id->num_alternatives;
6096
6097 /* Prepare to write out attribute subroutines by checking everything stored
6098 away and building the attribute cases. */
6099
6100 check_defs ();
6101 for (i = 0; i < MAX_ATTRS_INDEX; i++)
6102 for (attr = attrs[i]; attr; attr = attr->next)
6103 {
6104 attr->default_val->value
6105 = check_attr_value (attr->default_val->value, attr);
6106 fill_attr (attr);
6107 }
6108
6109 /* Construct extra attributes for `length'. */
6110 make_length_attrs ();
6111
6112 /* Perform any possible optimizations to speed up compilation. */
6113 optimize_attrs ();
6114
6115 /* Now write out all the `gen_attr_...' routines. Do these before the
6116 special routines (specifically before write_function_unit_info), so
6117 that they get defined before they are used. */
6118
6119 for (i = 0; i < MAX_ATTRS_INDEX; i++)
6120 for (attr = attrs[i]; attr; attr = attr->next)
6121 {
6122 if (! attr->is_special && ! attr->is_const)
6123 write_attr_get (attr);
6124 }
6125
6126 /* Write out delay eligibility information, if DEFINE_DELAY present.
6127 (The function to compute the number of delay slots will be written
6128 below.) */
6129 if (num_delays)
6130 {
6131 write_eligible_delay ("delay");
6132 if (have_annul_true)
6133 write_eligible_delay ("annul_true");
6134 if (have_annul_false)
6135 write_eligible_delay ("annul_false");
6136 }
6137
6138 /* Write out information about function units. */
6139 if (num_units)
6140 write_function_unit_info ();
6141
6142 /* Write out constant delay slot info */
6143 write_const_num_delay_slots ();
6144
6145 write_length_unit_log ();
6146
6147 fflush (stdout);
6148 exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
6149 /* NOTREACHED */
6150 return 0;
6151 }
6152
6153 /* Define this so we can link with print-rtl.o to get debug_rtx function. */
6154 const char *
6155 get_insn_name (code)
6156 int code;
6157 {
6158 return NULL;
6159 }