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