source: trunk/src/gcc/gcc/genattrtab.c@ 9

Last change on this file since 9 was 9, checked in by bird, 22 years ago

Applied initial diff from Platon.

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