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