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