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