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