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