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

Last change on this file since 1394 was 1394, checked in by bird, 21 years ago

#1040: Joined the GCC 3.3.3 with the trunk.

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