1 /* Generate code from machine description to compute values of attributes.
2 Copyright (C) 1991, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
3 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 /* This program handles insn attributes and the DEFINE_DELAY and
23 DEFINE_FUNCTION_UNIT definitions.
25 It produces a series of functions named `get_attr_...', one for each insn
26 attribute. Each of these is given the rtx for an insn and returns a member
27 of the enum for the attribute.
29 These subroutines have the form of a `switch' on the INSN_CODE (via
30 `recog_memoized'). Each case either returns a constant attribute value
31 or a value that depends on tests on other attributes, the form of
32 operands, or some random C expression (encoded with a SYMBOL_REF
35 If the attribute `alternative', or a random C expression is present,
36 `constrain_operands' is called. If either of these cases of a reference to
37 an operand is found, `insn_extract' is called.
39 The special attribute `length' is also recognized. For this operand,
40 expressions involving the address of an operand or the current insn,
41 (address (pc)), are valid. In this case, an initial pass is made to
42 set all lengths that do not depend on address. Those that do are set to
43 the maximum length. Then each insn that depends on an address is checked
44 and possibly has its length changed. The process repeats until no further
45 changed are made. The resulting lengths are saved for use by
48 A special form of DEFINE_ATTR, where the expression for default value is a
49 CONST expression, indicates an attribute that is constant for a given run
50 of the compiler. The subroutine generated for these attributes has no
51 parameters as it does not depend on any particular insn. Constant
52 attributes are typically used to specify which variety of processor is
55 Internal attributes are defined to handle DEFINE_DELAY and
56 DEFINE_FUNCTION_UNIT. Special routines are output for these cases.
58 This program works by keeping a list of possible values for each attribute.
59 These include the basic attribute choices, default values for attribute, and
60 all derived quantities.
62 As the description file is read, the definition for each insn is saved in a
63 `struct insn_def'. When the file reading is complete, a `struct insn_ent'
64 is created for each insn and chained to the corresponding attribute value,
65 either that specified, or the default.
67 An optimization phase is then run. This simplifies expressions for each
68 insn. EQ_ATTR tests are resolved, whenever possible, to a test that
69 indicates when the attribute has the specified value for the insn. This
70 avoids recursive calls during compilation.
72 The strategy used when processing DEFINE_DELAY and DEFINE_FUNCTION_UNIT
73 definitions is to create arbitrarily complex expressions and have the
74 optimization simplify them.
76 Once optimization is complete, any required routines and definitions
79 An optimization that is not yet implemented is to hoist the constant
80 expressions entirely out of the routines and definitions that are written.
81 A way to do this is to iterate over all possible combinations of values
82 for constant attributes and generate a set of functions for that given
83 combination. An initialization function would be written that evaluates
84 the attributes and installs the corresponding set of routines and
85 definitions (each would be accessed through a pointer).
87 We use the flags in an RTX as follows:
88 `unchanging' (RTX_UNCHANGING_P): This rtx is fully simplified
89 independent of the insn code.
90 `in_struct' (MEM_IN_STRUCT_P): This rtx is fully simplified
91 for the insn code currently being processed (see optimize_attrs).
92 `integrated' (RTX_INTEGRATED_P): This rtx is permanent and unique
94 `volatil' (MEM_VOLATILE_P): During simplify_by_exploding the value of an
95 EQ_ATTR rtx is true if !volatil and false if volatil. */
101 #include "insn-config.h" /* For REGISTER_CONSTRAINTS */
103 #ifdef HAVE_SYS_RESOURCE_H
104 # include <sys/resource.h>
107 /* We must include obstack.h after <sys/time.h>, to avoid lossage with
108 /usr/include/sys/stdtypes.h on Sun OS 4.x. */
111 static struct obstack obstack
, obstack1
, obstack2
;
112 struct obstack
*rtl_obstack
= &obstack
;
113 struct obstack
*hash_obstack
= &obstack1
;
114 struct obstack
*temp_obstack
= &obstack2
;
116 #define obstack_chunk_alloc xmalloc
117 #define obstack_chunk_free free
119 /* Define this so we can link with print-rtl.o to get debug_rtx function. */
120 char **insn_name_ptr
= 0;
123 extern rtx
read_rtx ();
126 void fatal
PVPROTO((char *, ...));
128 /* We must not provide any prototype here, even if ANSI C. */
129 void fatal
PROTO(());
133 /* enough space to reserve for printing out ints */
134 #define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3)
136 /* Define structures used to record attributes and values. */
138 /* As each DEFINE_INSN, DEFINE_PEEPHOLE, or DEFINE_ASM_ATTRIBUTES is
139 encountered, we store all the relevant information into a
140 `struct insn_def'. This is done to allow attribute definitions to occur
141 anywhere in the file. */
145 int insn_code
; /* Instruction number. */
146 int insn_index
; /* Expression numer in file, for errors. */
147 struct insn_def
*next
; /* Next insn in chain. */
148 rtx def
; /* The DEFINE_... */
149 int num_alternatives
; /* Number of alternatives. */
150 int vec_idx
; /* Index of attribute vector in `def'. */
153 /* Once everything has been read in, we store in each attribute value a list
154 of insn codes that have that value. Here is the structure used for the
159 int insn_code
; /* Instruction number. */
160 int insn_index
; /* Index of definition in file */
161 struct insn_ent
*next
; /* Next in chain. */
164 /* Each value of an attribute (either constant or computed) is assigned a
165 structure which is used as the listhead of the insns that have that
170 rtx value
; /* Value of attribute. */
171 struct attr_value
*next
; /* Next attribute value in chain. */
172 struct insn_ent
*first_insn
; /* First insn with this value. */
173 int num_insns
; /* Number of insns with this value. */
174 int has_asm_insn
; /* True if this value used for `asm' insns */
177 /* Structure for each attribute. */
181 char *name
; /* Name of attribute. */
182 struct attr_desc
*next
; /* Next attribute. */
183 int is_numeric
; /* Values of this attribute are numeric. */
184 int negative_ok
; /* Allow negative numeric values. */
185 int unsigned_p
; /* Make the output function unsigned int. */
186 int is_const
; /* Attribute value constant for each run. */
187 int is_special
; /* Don't call `write_attr_set'. */
188 struct attr_value
*first_value
; /* First value of this attribute. */
189 struct attr_value
*default_val
; /* Default value for this attribute. */
192 #define NULL_ATTR (struct attr_desc *) NULL
194 /* A range of values. */
202 /* Structure for each DEFINE_DELAY. */
206 rtx def
; /* DEFINE_DELAY expression. */
207 struct delay_desc
*next
; /* Next DEFINE_DELAY. */
208 int num
; /* Number of DEFINE_DELAY, starting at 1. */
211 /* Record information about each DEFINE_FUNCTION_UNIT. */
213 struct function_unit_op
215 rtx condexp
; /* Expression TRUE for applicable insn. */
216 struct function_unit_op
*next
; /* Next operation for this function unit. */
217 int num
; /* Ordinal for this operation type in unit. */
218 int ready
; /* Cost until data is ready. */
219 int issue_delay
; /* Cost until unit can accept another insn. */
220 rtx conflict_exp
; /* Expression TRUE for insns incurring issue delay. */
221 rtx issue_exp
; /* Expression computing issue delay. */
224 /* Record information about each function unit mentioned in a
225 DEFINE_FUNCTION_UNIT. */
229 char *name
; /* Function unit name. */
230 struct function_unit
*next
; /* Next function unit. */
231 int num
; /* Ordinal of this unit type. */
232 int multiplicity
; /* Number of units of this type. */
233 int simultaneity
; /* Maximum number of simultaneous insns
234 on this function unit or 0 if unlimited. */
235 rtx condexp
; /* Expression TRUE for insn needing unit. */
236 int num_opclasses
; /* Number of different operation types. */
237 struct function_unit_op
*ops
; /* Pointer to first operation type. */
238 int needs_conflict_function
; /* Nonzero if a conflict function required. */
239 int needs_blockage_function
; /* Nonzero if a blockage function required. */
240 int needs_range_function
; /* Nonzero if blockage range function needed.*/
241 rtx default_cost
; /* Conflict cost, if constant. */
242 struct range issue_delay
; /* Range of issue delay values. */
243 int max_blockage
; /* Maximum time an insn blocks the unit. */
246 /* Listheads of above structures. */
248 /* This one is indexed by the first character of the attribute name. */
249 #define MAX_ATTRS_INDEX 256
250 static struct attr_desc
*attrs
[MAX_ATTRS_INDEX
];
251 static struct insn_def
*defs
;
252 static struct delay_desc
*delays
;
253 static struct function_unit
*units
;
255 /* An expression where all the unknown terms are EQ_ATTR tests can be
256 rearranged into a COND provided we can enumerate all possible
257 combinations of the unknown values. The set of combinations become the
258 tests of the COND; the value of the expression given that combination is
259 computed and becomes the corresponding value. To do this, we must be
260 able to enumerate all values for each attribute used in the expression
261 (currently, we give up if we find a numeric attribute).
263 If the set of EQ_ATTR tests used in an expression tests the value of N
264 different attributes, the list of all possible combinations can be made
265 by walking the N-dimensional attribute space defined by those
266 attributes. We record each of these as a struct dimension.
268 The algorithm relies on sharing EQ_ATTR nodes: if two nodes in an
269 expression are the same, the will also have the same address. We find
270 all the EQ_ATTR nodes by marking them MEM_VOLATILE_P. This bit later
271 represents the value of an EQ_ATTR node, so once all nodes are marked,
272 they are also given an initial value of FALSE.
274 We then separate the set of EQ_ATTR nodes into dimensions for each
275 attribute and put them on the VALUES list. Terms are added as needed by
276 `add_values_to_cover' so that all possible values of the attribute are
279 Each dimension also has a current value. This is the node that is
280 currently considered to be TRUE. If this is one of the nodes added by
281 `add_values_to_cover', all the EQ_ATTR tests in the original expression
282 will be FALSE. Otherwise, only the CURRENT_VALUE will be true.
284 NUM_VALUES is simply the length of the VALUES list and is there for
287 Once the dimensions are created, the algorithm enumerates all possible
288 values and computes the current value of the given expression. */
292 struct attr_desc
*attr
; /* Attribute for this dimension. */
293 rtx values
; /* List of attribute values used. */
294 rtx current_value
; /* Position in the list for the TRUE value. */
295 int num_values
; /* Length of the values list. */
298 /* Other variables. */
300 static int insn_code_number
;
301 static int insn_index_number
;
302 static int got_define_asm_attributes
;
303 static int must_extract
;
304 static int must_constrain
;
305 static int address_used
;
306 static int length_used
;
307 static int num_delays
;
308 static int have_annul_true
, have_annul_false
;
309 static int num_units
;
310 static int num_insn_ents
;
312 /* Used as operand to `operate_exp': */
314 enum operator {PLUS_OP
, MINUS_OP
, POS_MINUS_OP
, EQ_OP
, OR_OP
, MAX_OP
, MIN_OP
, RANGE_OP
};
316 /* Stores, for each insn code, the number of constraint alternatives. */
318 static int *insn_n_alternatives
;
320 /* Stores, for each insn code, a bitmap that has bits on for each possible
323 static int *insn_alternatives
;
325 /* If nonzero, assume that the `alternative' attr has this value.
326 This is the hashed, unique string for the numeral
327 whose value is chosen alternative. */
329 static char *current_alternative_string
;
331 /* Used to simplify expressions. */
333 static rtx true_rtx
, false_rtx
;
335 /* Used to reduce calls to `strcmp' */
337 static char *alternative_name
;
339 /* Indicate that REG_DEAD notes are valid if dead_or_set_p is ever
342 int reload_completed
= 0;
344 /* Some machines test `optimize' in macros called from rtlanal.c, so we need
345 to define it here. */
349 /* Simplify an expression. Only call the routine if there is something to
351 #define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX) \
352 (RTX_UNCHANGING_P (EXP) || MEM_IN_STRUCT_P (EXP) ? (EXP) \
353 : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
355 /* Simplify (eq_attr ("alternative") ...)
356 when we are working with a particular alternative. */
357 #define SIMPLIFY_ALTERNATIVE(EXP) \
358 if (current_alternative_string \
359 && GET_CODE ((EXP)) == EQ_ATTR \
360 && XSTR ((EXP), 0) == alternative_name) \
361 (EXP) = (XSTR ((EXP), 1) == current_alternative_string \
362 ? true_rtx : false_rtx);
364 /* These are referenced by rtlanal.c and hence need to be defined somewhere.
365 They won't actually be used. */
367 rtx frame_pointer_rtx
, hard_frame_pointer_rtx
, stack_pointer_rtx
;
368 rtx arg_pointer_rtx
, pic_offset_table_rtx
;
370 static rtx attr_rtx
PVPROTO((enum rtx_code
, ...));
372 static char *attr_printf
PVPROTO((int, char *, ...));
374 static char *attr_printf ();
377 static char *attr_string
PROTO((char *, int));
378 static rtx check_attr_test
PROTO((rtx
, int));
379 static rtx check_attr_value
PROTO((rtx
, struct attr_desc
*));
380 static rtx convert_set_attr_alternative
PROTO((rtx
, int, int, int));
381 static rtx convert_set_attr
PROTO((rtx
, int, int, int));
382 static void check_defs
PROTO((void));
383 static rtx convert_const_symbol_ref
PROTO((rtx
, struct attr_desc
*));
384 static rtx make_canonical
PROTO((struct attr_desc
*, rtx
));
385 static struct attr_value
*get_attr_value
PROTO((rtx
, struct attr_desc
*, int));
386 static rtx copy_rtx_unchanging
PROTO((rtx
));
387 static rtx copy_boolean
PROTO((rtx
));
388 static void expand_delays
PROTO((void));
389 static rtx operate_exp
PROTO((enum operator, rtx
, rtx
));
390 static void expand_units
PROTO((void));
391 static rtx simplify_knowing
PROTO((rtx
, rtx
));
392 static rtx encode_units_mask
PROTO((rtx
));
393 static void fill_attr
PROTO((struct attr_desc
*));
394 /* dpx2 compiler chokes if we specify the arg types of the args. */
395 static rtx substitute_address
PROTO((rtx
, rtx (*) (), rtx (*) ()));
396 static void make_length_attrs
PROTO((void));
397 static rtx identity_fn
PROTO((rtx
));
398 static rtx zero_fn
PROTO((rtx
));
399 static rtx one_fn
PROTO((rtx
));
400 static rtx max_fn
PROTO((rtx
));
401 static rtx simplify_cond
PROTO((rtx
, int, int));
403 static rtx simplify_by_alternatives
PROTO((rtx
, int, int));
405 static rtx simplify_by_exploding
PROTO((rtx
));
406 static int find_and_mark_used_attributes
PROTO((rtx
, rtx
*, int *));
407 static void unmark_used_attributes
PROTO((rtx
, struct dimension
*, int));
408 static int add_values_to_cover
PROTO((struct dimension
*));
409 static int increment_current_value
PROTO((struct dimension
*, int));
410 static rtx test_for_current_value
PROTO((struct dimension
*, int));
411 static rtx simplify_with_current_value
PROTO((rtx
, struct dimension
*, int));
412 static rtx simplify_with_current_value_aux
PROTO((rtx
));
413 static void clear_struct_flag
PROTO((rtx
));
414 static int count_sub_rtxs
PROTO((rtx
, int));
415 static void remove_insn_ent
PROTO((struct attr_value
*, struct insn_ent
*));
416 static void insert_insn_ent
PROTO((struct attr_value
*, struct insn_ent
*));
417 static rtx insert_right_side
PROTO((enum rtx_code
, rtx
, rtx
, int, int));
418 static rtx make_alternative_compare
PROTO((int));
419 static int compute_alternative_mask
PROTO((rtx
, enum rtx_code
));
420 static rtx evaluate_eq_attr
PROTO((rtx
, rtx
, int, int));
421 static rtx simplify_and_tree
PROTO((rtx
, rtx
*, int, int));
422 static rtx simplify_or_tree
PROTO((rtx
, rtx
*, int, int));
423 static rtx simplify_test_exp
PROTO((rtx
, int, int));
424 static void optimize_attrs
PROTO((void));
425 static void gen_attr
PROTO((rtx
));
426 static int count_alternatives
PROTO((rtx
));
427 static int compares_alternatives_p
PROTO((rtx
));
428 static int contained_in_p
PROTO((rtx
, rtx
));
429 static void gen_insn
PROTO((rtx
));
430 static void gen_delay
PROTO((rtx
));
431 static void gen_unit
PROTO((rtx
));
432 static void write_test_expr
PROTO((rtx
, int));
433 static int max_attr_value
PROTO((rtx
));
434 static void walk_attr_value
PROTO((rtx
));
435 static void write_attr_get
PROTO((struct attr_desc
*));
436 static rtx eliminate_known_true
PROTO((rtx
, rtx
, int, int));
437 static void write_attr_set
PROTO((struct attr_desc
*, int, rtx
, char *,
438 char *, rtx
, int, int));
439 static void write_attr_case
PROTO((struct attr_desc
*, struct attr_value
*,
440 int, char *, char *, int, rtx
));
441 static void write_attr_valueq
PROTO((struct attr_desc
*, char *));
442 static void write_attr_value
PROTO((struct attr_desc
*, rtx
));
443 static void write_upcase
PROTO((char *));
444 static void write_indent
PROTO((int));
445 static void write_eligible_delay
PROTO((char *));
446 static void write_function_unit_info
PROTO((void));
447 static void write_complex_function
PROTO((struct function_unit
*, char *,
449 static int n_comma_elts
PROTO((char *));
450 static char *next_comma_elt
PROTO((char **));
451 static struct attr_desc
*find_attr
PROTO((char *, int));
452 static void make_internal_attr
PROTO((char *, rtx
, int));
453 static struct attr_value
*find_most_used
PROTO((struct attr_desc
*));
454 static rtx find_single_value
PROTO((struct attr_desc
*));
455 static rtx make_numeric_value
PROTO((int));
456 static void extend_range
PROTO((struct range
*, int, int));
457 char *xrealloc
PROTO((char *, unsigned));
458 char *xmalloc
PROTO((unsigned));
460 #define oballoc(size) obstack_alloc (hash_obstack, size)
463 /* Hash table for sharing RTL and strings. */
465 /* Each hash table slot is a bucket containing a chain of these structures.
466 Strings are given negative hash codes; RTL expressions are given positive
471 struct attr_hash
*next
; /* Next structure in the bucket. */
472 int hashcode
; /* Hash code of this rtx or string. */
475 char *str
; /* The string (negative hash codes) */
476 rtx rtl
; /* or the RTL recorded here. */
480 /* Now here is the hash table. When recording an RTL, it is added to
481 the slot whose index is the hash code mod the table size. Note
482 that the hash table is used for several kinds of RTL (see attr_rtx)
483 and for strings. While all these live in the same table, they are
484 completely independent, and the hash code is computed differently
487 #define RTL_HASH_SIZE 4093
488 struct attr_hash
*attr_hash_table
[RTL_HASH_SIZE
];
490 /* Here is how primitive or already-shared RTL's hash
492 #define RTL_HASH(RTL) ((HOST_WIDE_INT) (RTL) & 0777777)
496 /* Add an entry to the hash table for RTL with hash code HASHCODE. */
499 attr_hash_add_rtx (hashcode
, rtl
)
503 register struct attr_hash
*h
;
505 h
= (struct attr_hash
*) obstack_alloc (hash_obstack
,
506 sizeof (struct attr_hash
));
507 h
->hashcode
= hashcode
;
509 h
->next
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
];
510 attr_hash_table
[hashcode
% RTL_HASH_SIZE
] = h
;
513 /* Add an entry to the hash table for STRING with hash code HASHCODE. */
516 attr_hash_add_string (hashcode
, str
)
520 register struct attr_hash
*h
;
522 h
= (struct attr_hash
*) obstack_alloc (hash_obstack
,
523 sizeof (struct attr_hash
));
524 h
->hashcode
= -hashcode
;
526 h
->next
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
];
527 attr_hash_table
[hashcode
% RTL_HASH_SIZE
] = h
;
530 /* Generate an RTL expression, but avoid duplicates.
531 Set the RTX_INTEGRATED_P flag for these permanent objects.
533 In some cases we cannot uniquify; then we return an ordinary
534 impermanent rtx with RTX_INTEGRATED_P clear.
536 Args are like gen_rtx, but without the mode:
538 rtx attr_rtx (code, [element1, ..., elementn]) */
542 attr_rtx
VPROTO((enum rtx_code code
, ...))
544 #ifndef ANSI_PROTOTYPES
548 register int i
; /* Array indices... */
549 register char *fmt
; /* Current rtx's format... */
550 register rtx rt_val
; /* RTX to return to caller... */
552 register struct attr_hash
*h
;
553 struct obstack
*old_obstack
= rtl_obstack
;
557 #ifndef ANSI_PROTOTYPES
558 code
= va_arg (p
, enum rtx_code
);
561 /* For each of several cases, search the hash table for an existing entry.
562 Use that entry if one is found; otherwise create a new RTL and add it
565 if (GET_RTX_CLASS (code
) == '1')
567 rtx arg0
= va_arg (p
, rtx
);
569 /* A permanent object cannot point to impermanent ones. */
570 if (! RTX_INTEGRATED_P (arg0
))
572 rt_val
= rtx_alloc (code
);
573 XEXP (rt_val
, 0) = arg0
;
578 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
));
579 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
580 if (h
->hashcode
== hashcode
581 && GET_CODE (h
->u
.rtl
) == code
582 && XEXP (h
->u
.rtl
, 0) == arg0
)
587 rtl_obstack
= hash_obstack
;
588 rt_val
= rtx_alloc (code
);
589 XEXP (rt_val
, 0) = arg0
;
592 else if (GET_RTX_CLASS (code
) == 'c'
593 || GET_RTX_CLASS (code
) == '2'
594 || GET_RTX_CLASS (code
) == '<')
596 rtx arg0
= va_arg (p
, rtx
);
597 rtx arg1
= va_arg (p
, rtx
);
599 /* A permanent object cannot point to impermanent ones. */
600 if (! RTX_INTEGRATED_P (arg0
) || ! RTX_INTEGRATED_P (arg1
))
602 rt_val
= rtx_alloc (code
);
603 XEXP (rt_val
, 0) = arg0
;
604 XEXP (rt_val
, 1) = arg1
;
609 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
) + RTL_HASH (arg1
));
610 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
611 if (h
->hashcode
== hashcode
612 && GET_CODE (h
->u
.rtl
) == code
613 && XEXP (h
->u
.rtl
, 0) == arg0
614 && XEXP (h
->u
.rtl
, 1) == arg1
)
619 rtl_obstack
= hash_obstack
;
620 rt_val
= rtx_alloc (code
);
621 XEXP (rt_val
, 0) = arg0
;
622 XEXP (rt_val
, 1) = arg1
;
625 else if (GET_RTX_LENGTH (code
) == 1
626 && GET_RTX_FORMAT (code
)[0] == 's')
628 char * arg0
= va_arg (p
, char *);
630 if (code
== SYMBOL_REF
)
631 arg0
= attr_string (arg0
, strlen (arg0
));
633 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
));
634 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
635 if (h
->hashcode
== hashcode
636 && GET_CODE (h
->u
.rtl
) == code
637 && XSTR (h
->u
.rtl
, 0) == arg0
)
642 rtl_obstack
= hash_obstack
;
643 rt_val
= rtx_alloc (code
);
644 XSTR (rt_val
, 0) = arg0
;
647 else if (GET_RTX_LENGTH (code
) == 2
648 && GET_RTX_FORMAT (code
)[0] == 's'
649 && GET_RTX_FORMAT (code
)[1] == 's')
651 char *arg0
= va_arg (p
, char *);
652 char *arg1
= va_arg (p
, char *);
654 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
) + RTL_HASH (arg1
));
655 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
656 if (h
->hashcode
== hashcode
657 && GET_CODE (h
->u
.rtl
) == code
658 && XSTR (h
->u
.rtl
, 0) == arg0
659 && XSTR (h
->u
.rtl
, 1) == arg1
)
664 rtl_obstack
= hash_obstack
;
665 rt_val
= rtx_alloc (code
);
666 XSTR (rt_val
, 0) = arg0
;
667 XSTR (rt_val
, 1) = arg1
;
670 else if (code
== CONST_INT
)
672 HOST_WIDE_INT arg0
= va_arg (p
, HOST_WIDE_INT
);
682 rt_val
= rtx_alloc (code
); /* Allocate the storage space. */
684 fmt
= GET_RTX_FORMAT (code
); /* Find the right format... */
685 for (i
= 0; i
< GET_RTX_LENGTH (code
); i
++)
689 case '0': /* Unused field. */
692 case 'i': /* An integer? */
693 XINT (rt_val
, i
) = va_arg (p
, int);
696 case 'w': /* A wide integer? */
697 XWINT (rt_val
, i
) = va_arg (p
, HOST_WIDE_INT
);
700 case 's': /* A string? */
701 XSTR (rt_val
, i
) = va_arg (p
, char *);
704 case 'e': /* An expression? */
705 case 'u': /* An insn? Same except when printing. */
706 XEXP (rt_val
, i
) = va_arg (p
, rtx
);
709 case 'E': /* An RTX vector? */
710 XVEC (rt_val
, i
) = va_arg (p
, rtvec
);
721 rtl_obstack
= old_obstack
;
723 attr_hash_add_rtx (hashcode
, rt_val
);
724 RTX_INTEGRATED_P (rt_val
) = 1;
732 /* Create a new string printed with the printf line arguments into a space
733 of at most LEN bytes:
735 rtx attr_printf (len, format, [arg1, ..., argn]) */
741 attr_printf
VPROTO((register int len
, char *fmt
, ...))
743 #ifndef ANSI_PROTOTYPES
752 #ifndef ANSI_PROTOTYPES
753 len
= va_arg (p
, int);
754 fmt
= va_arg (p
, char *);
757 /* Print the string into a temporary location. */
758 str
= (char *) alloca (len
);
759 vsprintf (str
, fmt
, p
);
762 return attr_string (str
, strlen (str
));
765 #else /* not HAVE_VPRINTF */
768 attr_printf (len
, fmt
, arg1
, arg2
, arg3
)
771 char *arg1
, *arg2
, *arg3
; /* also int */
775 /* Print the string into a temporary location. */
776 str
= (char *) alloca (len
);
777 sprintf (str
, fmt
, arg1
, arg2
, arg3
);
779 return attr_string (str
, strlen (str
));
781 #endif /* not HAVE_VPRINTF */
784 attr_eq (name
, value
)
787 return attr_rtx (EQ_ATTR
, attr_string (name
, strlen (name
)),
788 attr_string (value
, strlen (value
)));
795 return XSTR (make_numeric_value (n
), 0);
798 /* Return a permanent (possibly shared) copy of a string STR (not assumed
799 to be null terminated) with LEN bytes. */
802 attr_string (str
, len
)
806 register struct attr_hash
*h
;
809 register char *new_str
;
811 /* Compute the hash code. */
812 hashcode
= (len
+ 1) * 613 + (unsigned)str
[0];
813 for (i
= 1; i
<= len
; i
+= 2)
814 hashcode
= ((hashcode
* 613) + (unsigned)str
[i
]);
816 hashcode
= -hashcode
;
818 /* Search the table for the string. */
819 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
820 if (h
->hashcode
== -hashcode
&& h
->u
.str
[0] == str
[0]
821 && !strncmp (h
->u
.str
, str
, len
))
822 return h
->u
.str
; /* <-- return if found. */
824 /* Not found; create a permanent copy and add it to the hash table. */
825 new_str
= (char *) obstack_alloc (hash_obstack
, len
+ 1);
826 bcopy (str
, new_str
, len
);
828 attr_hash_add_string (hashcode
, new_str
);
830 return new_str
; /* Return the new string. */
833 /* Check two rtx's for equality of contents,
834 taking advantage of the fact that if both are hashed
835 then they can't be equal unless they are the same object. */
841 return (x
== y
|| (! (RTX_INTEGRATED_P (x
) && RTX_INTEGRATED_P (y
))
842 && rtx_equal_p (x
, y
)));
845 /* Copy an attribute value expression,
846 descending to all depths, but not copying any
847 permanent hashed subexpressions. */
855 register RTX_CODE code
;
856 register char *format_ptr
;
858 /* No need to copy a permanent object. */
859 if (RTX_INTEGRATED_P (orig
))
862 code
= GET_CODE (orig
);
880 copy
= rtx_alloc (code
);
881 PUT_MODE (copy
, GET_MODE (orig
));
882 copy
->in_struct
= orig
->in_struct
;
883 copy
->volatil
= orig
->volatil
;
884 copy
->unchanging
= orig
->unchanging
;
885 copy
->integrated
= orig
->integrated
;
887 format_ptr
= GET_RTX_FORMAT (GET_CODE (copy
));
889 for (i
= 0; i
< GET_RTX_LENGTH (GET_CODE (copy
)); i
++)
891 switch (*format_ptr
++)
894 XEXP (copy
, i
) = XEXP (orig
, i
);
895 if (XEXP (orig
, i
) != NULL
)
896 XEXP (copy
, i
) = attr_copy_rtx (XEXP (orig
, i
));
901 XVEC (copy
, i
) = XVEC (orig
, i
);
902 if (XVEC (orig
, i
) != NULL
)
904 XVEC (copy
, i
) = rtvec_alloc (XVECLEN (orig
, i
));
905 for (j
= 0; j
< XVECLEN (copy
, i
); j
++)
906 XVECEXP (copy
, i
, j
) = attr_copy_rtx (XVECEXP (orig
, i
, j
));
912 XINT (copy
, i
) = XINT (orig
, i
);
916 XWINT (copy
, i
) = XWINT (orig
, i
);
921 XSTR (copy
, i
) = XSTR (orig
, i
);
931 /* Given a test expression for an attribute, ensure it is validly formed.
932 IS_CONST indicates whether the expression is constant for each compiler
933 run (a constant expression may not test any particular insn).
935 Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
936 and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
937 test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
939 Update the string address in EQ_ATTR expression to be the same used
940 in the attribute (or `alternative_name') to speed up subsequent
941 `find_attr' calls and eliminate most `strcmp' calls.
943 Return the new expression, if any. */
946 check_attr_test (exp
, is_const
)
950 struct attr_desc
*attr
;
951 struct attr_value
*av
;
955 switch (GET_CODE (exp
))
958 /* Handle negation test. */
959 if (XSTR (exp
, 1)[0] == '!')
960 return check_attr_test (attr_rtx (NOT
,
961 attr_eq (XSTR (exp
, 0),
965 else if (n_comma_elts (XSTR (exp
, 1)) == 1)
967 attr
= find_attr (XSTR (exp
, 0), 0);
970 if (! strcmp (XSTR (exp
, 0), "alternative"))
972 XSTR (exp
, 0) = alternative_name
;
973 /* This can't be simplified any further. */
974 RTX_UNCHANGING_P (exp
) = 1;
978 fatal ("Unknown attribute `%s' in EQ_ATTR", XEXP (exp
, 0));
981 if (is_const
&& ! attr
->is_const
)
982 fatal ("Constant expression uses insn attribute `%s' in EQ_ATTR",
985 /* Copy this just to make it permanent,
986 so expressions using it can be permanent too. */
987 exp
= attr_eq (XSTR (exp
, 0), XSTR (exp
, 1));
989 /* It shouldn't be possible to simplify the value given to a
990 constant attribute, so don't expand this until it's time to
991 write the test expression. */
993 RTX_UNCHANGING_P (exp
) = 1;
995 if (attr
->is_numeric
)
997 for (p
= XSTR (exp
, 1); *p
; p
++)
998 if (*p
< '0' || *p
> '9')
999 fatal ("Attribute `%s' takes only numeric values",
1004 for (av
= attr
->first_value
; av
; av
= av
->next
)
1005 if (GET_CODE (av
->value
) == CONST_STRING
1006 && ! strcmp (XSTR (exp
, 1), XSTR (av
->value
, 0)))
1010 fatal ("Unknown value `%s' for `%s' attribute",
1011 XEXP (exp
, 1), XEXP (exp
, 0));
1016 /* Make an IOR tree of the possible values. */
1018 name_ptr
= XSTR (exp
, 1);
1019 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
1021 newexp
= attr_eq (XSTR (exp
, 0), p
);
1022 orexp
= insert_right_side (IOR
, orexp
, newexp
, -2, -2);
1025 return check_attr_test (orexp
, is_const
);
1033 /* Either TRUE or FALSE. */
1041 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0), is_const
);
1042 XEXP (exp
, 1) = check_attr_test (XEXP (exp
, 1), is_const
);
1046 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0), is_const
);
1051 fatal ("RTL operator \"%s\" not valid in constant attribute test",
1052 GET_RTX_NAME (MATCH_OPERAND
));
1053 /* These cases can't be simplified. */
1054 RTX_UNCHANGING_P (exp
) = 1;
1057 case LE
: case LT
: case GT
: case GE
:
1058 case LEU
: case LTU
: case GTU
: case GEU
:
1060 if (GET_CODE (XEXP (exp
, 0)) == SYMBOL_REF
1061 && GET_CODE (XEXP (exp
, 1)) == SYMBOL_REF
)
1062 exp
= attr_rtx (GET_CODE (exp
),
1063 attr_rtx (SYMBOL_REF
, XSTR (XEXP (exp
, 0), 0)),
1064 attr_rtx (SYMBOL_REF
, XSTR (XEXP (exp
, 1), 0)));
1065 /* These cases can't be simplified. */
1066 RTX_UNCHANGING_P (exp
) = 1;
1072 /* These cases are valid for constant attributes, but can't be
1074 exp
= attr_rtx (SYMBOL_REF
, XSTR (exp
, 0));
1075 RTX_UNCHANGING_P (exp
) = 1;
1079 fatal ("RTL operator \"%s\" not valid in attribute test",
1080 GET_RTX_NAME (GET_CODE (exp
)));
1086 /* Given an expression, ensure that it is validly formed and that all named
1087 attribute values are valid for the given attribute. Issue a fatal error
1088 if not. If no attribute is specified, assume a numeric attribute.
1090 Return a perhaps modified replacement expression for the value. */
1093 check_attr_value (exp
, attr
)
1095 struct attr_desc
*attr
;
1097 struct attr_value
*av
;
1101 switch (GET_CODE (exp
))
1104 if (attr
&& ! attr
->is_numeric
)
1105 fatal ("CONST_INT not valid for non-numeric `%s' attribute",
1108 if (INTVAL (exp
) < 0)
1109 fatal ("Negative numeric value specified for `%s' attribute",
1115 if (! strcmp (XSTR (exp
, 0), "*"))
1118 if (attr
== 0 || attr
->is_numeric
)
1121 if (attr
&& attr
->negative_ok
&& *p
== '-')
1124 if (*p
> '9' || *p
< '0')
1125 fatal ("Non-numeric value for numeric `%s' attribute",
1126 attr
? attr
->name
: "internal");
1130 for (av
= attr
->first_value
; av
; av
= av
->next
)
1131 if (GET_CODE (av
->value
) == CONST_STRING
1132 && ! strcmp (XSTR (av
->value
, 0), XSTR (exp
, 0)))
1136 fatal ("Unknown value `%s' for `%s' attribute",
1137 XSTR (exp
, 0), attr
? attr
->name
: "internal");
1142 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0),
1143 attr
? attr
->is_const
: 0);
1144 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
1145 XEXP (exp
, 2) = check_attr_value (XEXP (exp
, 2), attr
);
1149 if (XVECLEN (exp
, 0) % 2 != 0)
1150 fatal ("First operand of COND must have even length");
1152 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1154 XVECEXP (exp
, 0, i
) = check_attr_test (XVECEXP (exp
, 0, i
),
1155 attr
? attr
->is_const
: 0);
1156 XVECEXP (exp
, 0, i
+ 1)
1157 = check_attr_value (XVECEXP (exp
, 0, i
+ 1), attr
);
1160 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
1164 if (attr
&& attr
->is_const
)
1165 /* A constant SYMBOL_REF is valid as a constant attribute test and
1166 is expanded later by make_canonical into a COND. */
1167 return attr_rtx (SYMBOL_REF
, XSTR (exp
, 0));
1168 /* Otherwise, fall through... */
1171 fatal ("Invalid operation `%s' for attribute value",
1172 GET_RTX_NAME (GET_CODE (exp
)));
1178 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
1179 It becomes a COND with each test being (eq_attr "alternative "n") */
1182 convert_set_attr_alternative (exp
, num_alt
, insn_code
, insn_index
)
1185 int insn_code
, insn_index
;
1190 if (XVECLEN (exp
, 1) != num_alt
)
1191 fatal ("Bad number of entries in SET_ATTR_ALTERNATIVE for insn %d",
1194 /* Make a COND with all tests but the last. Select the last value via the
1196 condexp
= rtx_alloc (COND
);
1197 XVEC (condexp
, 0) = rtvec_alloc ((num_alt
- 1) * 2);
1199 for (i
= 0; i
< num_alt
- 1; i
++)
1202 p
= attr_numeral (i
);
1204 XVECEXP (condexp
, 0, 2 * i
) = attr_eq (alternative_name
, p
);
1206 /* Sharing this EQ_ATTR rtl causes trouble. */
1207 XVECEXP (condexp
, 0, 2 * i
) = rtx_alloc (EQ_ATTR
);
1208 XSTR (XVECEXP (condexp
, 0, 2 * i
), 0) = alternative_name
;
1209 XSTR (XVECEXP (condexp
, 0, 2 * i
), 1) = p
;
1211 XVECEXP (condexp
, 0, 2 * i
+ 1) = XVECEXP (exp
, 1, i
);
1214 XEXP (condexp
, 1) = XVECEXP (exp
, 1, i
);
1216 return attr_rtx (SET
, attr_rtx (ATTR
, XSTR (exp
, 0)), condexp
);
1219 /* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
1220 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
1223 convert_set_attr (exp
, num_alt
, insn_code
, insn_index
)
1226 int insn_code
, insn_index
;
1233 /* See how many alternative specified. */
1234 n
= n_comma_elts (XSTR (exp
, 1));
1236 return attr_rtx (SET
,
1237 attr_rtx (ATTR
, XSTR (exp
, 0)),
1238 attr_rtx (CONST_STRING
, XSTR (exp
, 1)));
1240 newexp
= rtx_alloc (SET_ATTR_ALTERNATIVE
);
1241 XSTR (newexp
, 0) = XSTR (exp
, 0);
1242 XVEC (newexp
, 1) = rtvec_alloc (n
);
1244 /* Process each comma-separated name. */
1245 name_ptr
= XSTR (exp
, 1);
1247 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
1248 XVECEXP (newexp
, 1, n
++) = attr_rtx (CONST_STRING
, p
);
1250 return convert_set_attr_alternative (newexp
, num_alt
, insn_code
, insn_index
);
1253 /* Scan all definitions, checking for validity. Also, convert any SET_ATTR
1254 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
1260 struct insn_def
*id
;
1261 struct attr_desc
*attr
;
1265 for (id
= defs
; id
; id
= id
->next
)
1267 if (XVEC (id
->def
, id
->vec_idx
) == NULL
)
1270 for (i
= 0; i
< XVECLEN (id
->def
, id
->vec_idx
); i
++)
1272 value
= XVECEXP (id
->def
, id
->vec_idx
, i
);
1273 switch (GET_CODE (value
))
1276 if (GET_CODE (XEXP (value
, 0)) != ATTR
)
1277 fatal ("Bad attribute set in pattern %d", id
->insn_index
);
1280 case SET_ATTR_ALTERNATIVE
:
1281 value
= convert_set_attr_alternative (value
,
1282 id
->num_alternatives
,
1288 value
= convert_set_attr (value
, id
->num_alternatives
,
1289 id
->insn_code
, id
->insn_index
);
1293 fatal ("Invalid attribute code `%s' for pattern %d",
1294 GET_RTX_NAME (GET_CODE (value
)), id
->insn_index
);
1297 if ((attr
= find_attr (XSTR (XEXP (value
, 0), 0), 0)) == NULL
)
1298 fatal ("Unknown attribute `%s' for pattern number %d",
1299 XSTR (XEXP (value
, 0), 0), id
->insn_index
);
1301 XVECEXP (id
->def
, id
->vec_idx
, i
) = value
;
1302 XEXP (value
, 1) = check_attr_value (XEXP (value
, 1), attr
);
1307 /* Given a constant SYMBOL_REF expression, convert to a COND that
1308 explicitly tests each enumerated value. */
1311 convert_const_symbol_ref (exp
, attr
)
1313 struct attr_desc
*attr
;
1316 struct attr_value
*av
;
1320 for (av
= attr
->first_value
; av
; av
= av
->next
)
1323 /* Make a COND with all tests but the last, and in the original order.
1324 Select the last value via the default. Note that the attr values
1325 are constructed in reverse order. */
1327 condexp
= rtx_alloc (COND
);
1328 XVEC (condexp
, 0) = rtvec_alloc ((num_alt
- 1) * 2);
1329 av
= attr
->first_value
;
1330 XEXP (condexp
, 1) = av
->value
;
1332 for (i
= num_alt
- 2; av
= av
->next
, i
>= 0; i
--)
1337 string
= p
= (char *) oballoc (2
1338 + strlen (attr
->name
)
1339 + strlen (XSTR (av
->value
, 0)));
1340 strcpy (p
, attr
->name
);
1342 strcat (p
, XSTR (av
->value
, 0));
1343 for (; *p
!= '\0'; p
++)
1344 if (*p
>= 'a' && *p
<= 'z')
1347 value
= attr_rtx (SYMBOL_REF
, string
);
1348 RTX_UNCHANGING_P (value
) = 1;
1350 XVECEXP (condexp
, 0, 2 * i
) = attr_rtx (EQ
, exp
, value
);
1352 XVECEXP (condexp
, 0, 2 * i
+ 1) = av
->value
;
1358 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1359 expressions by converting them into a COND. This removes cases from this
1360 program. Also, replace an attribute value of "*" with the default attribute
1364 make_canonical (attr
, exp
)
1365 struct attr_desc
*attr
;
1371 switch (GET_CODE (exp
))
1374 exp
= make_numeric_value (INTVAL (exp
));
1378 if (! strcmp (XSTR (exp
, 0), "*"))
1380 if (attr
== 0 || attr
->default_val
== 0)
1381 fatal ("(attr_value \"*\") used in invalid context.");
1382 exp
= attr
->default_val
->value
;
1388 if (!attr
->is_const
|| RTX_UNCHANGING_P (exp
))
1390 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1391 This makes the COND something that won't be considered an arbitrary
1392 expression by walk_attr_value. */
1393 RTX_UNCHANGING_P (exp
) = 1;
1394 exp
= convert_const_symbol_ref (exp
, attr
);
1395 RTX_UNCHANGING_P (exp
) = 1;
1396 exp
= check_attr_value (exp
, attr
);
1397 /* Goto COND case since this is now a COND. Note that while the
1398 new expression is rescanned, all symbol_ref notes are marked as
1403 newexp
= rtx_alloc (COND
);
1404 XVEC (newexp
, 0) = rtvec_alloc (2);
1405 XVECEXP (newexp
, 0, 0) = XEXP (exp
, 0);
1406 XVECEXP (newexp
, 0, 1) = XEXP (exp
, 1);
1408 XEXP (newexp
, 1) = XEXP (exp
, 2);
1411 /* Fall through to COND case since this is now a COND. */
1419 /* First, check for degenerate COND. */
1420 if (XVECLEN (exp
, 0) == 0)
1421 return make_canonical (attr
, XEXP (exp
, 1));
1422 defval
= XEXP (exp
, 1) = make_canonical (attr
, XEXP (exp
, 1));
1424 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1426 XVECEXP (exp
, 0, i
) = copy_boolean (XVECEXP (exp
, 0, i
));
1427 XVECEXP (exp
, 0, i
+ 1)
1428 = make_canonical (attr
, XVECEXP (exp
, 0, i
+ 1));
1429 if (! rtx_equal_p (XVECEXP (exp
, 0, i
+ 1), defval
))
1448 if (GET_CODE (exp
) == AND
|| GET_CODE (exp
) == IOR
)
1449 return attr_rtx (GET_CODE (exp
), copy_boolean (XEXP (exp
, 0)),
1450 copy_boolean (XEXP (exp
, 1)));
1454 /* Given a value and an attribute description, return a `struct attr_value *'
1455 that represents that value. This is either an existing structure, if the
1456 value has been previously encountered, or a newly-created structure.
1458 `insn_code' is the code of an insn whose attribute has the specified
1459 value (-2 if not processing an insn). We ensure that all insns for
1460 a given value have the same number of alternatives if the value checks
1463 static struct attr_value
*
1464 get_attr_value (value
, attr
, insn_code
)
1466 struct attr_desc
*attr
;
1469 struct attr_value
*av
;
1472 value
= make_canonical (attr
, value
);
1473 if (compares_alternatives_p (value
))
1475 if (insn_code
< 0 || insn_alternatives
== NULL
)
1476 fatal ("(eq_attr \"alternatives\" ...) used in non-insn context");
1478 num_alt
= insn_alternatives
[insn_code
];
1481 for (av
= attr
->first_value
; av
; av
= av
->next
)
1482 if (rtx_equal_p (value
, av
->value
)
1483 && (num_alt
== 0 || av
->first_insn
== NULL
1484 || insn_alternatives
[av
->first_insn
->insn_code
]))
1487 av
= (struct attr_value
*) oballoc (sizeof (struct attr_value
));
1489 av
->next
= attr
->first_value
;
1490 attr
->first_value
= av
;
1491 av
->first_insn
= NULL
;
1493 av
->has_asm_insn
= 0;
1498 /* After all DEFINE_DELAYs have been read in, create internal attributes
1499 to generate the required routines.
1501 First, we compute the number of delay slots for each insn (as a COND of
1502 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1503 delay type is specified, we compute a similar function giving the
1504 DEFINE_DELAY ordinal for each insn.
1506 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1507 tells whether a given insn can be in that delay slot.
1509 Normal attribute filling and optimization expands these to contain the
1510 information needed to handle delay slots. */
1515 struct delay_desc
*delay
;
1521 /* First, generate data for `num_delay_slots' function. */
1523 condexp
= rtx_alloc (COND
);
1524 XVEC (condexp
, 0) = rtvec_alloc (num_delays
* 2);
1525 XEXP (condexp
, 1) = make_numeric_value (0);
1527 for (i
= 0, delay
= delays
; delay
; i
+= 2, delay
= delay
->next
)
1529 XVECEXP (condexp
, 0, i
) = XEXP (delay
->def
, 0);
1530 XVECEXP (condexp
, 0, i
+ 1)
1531 = make_numeric_value (XVECLEN (delay
->def
, 1) / 3);
1534 make_internal_attr ("*num_delay_slots", condexp
, 0);
1536 /* If more than one delay type, do the same for computing the delay type. */
1539 condexp
= rtx_alloc (COND
);
1540 XVEC (condexp
, 0) = rtvec_alloc (num_delays
* 2);
1541 XEXP (condexp
, 1) = make_numeric_value (0);
1543 for (i
= 0, delay
= delays
; delay
; i
+= 2, delay
= delay
->next
)
1545 XVECEXP (condexp
, 0, i
) = XEXP (delay
->def
, 0);
1546 XVECEXP (condexp
, 0, i
+ 1) = make_numeric_value (delay
->num
);
1549 make_internal_attr ("*delay_type", condexp
, 1);
1552 /* For each delay possibility and delay slot, compute an eligibility
1553 attribute for non-annulled insns and for each type of annulled (annul
1554 if true and annul if false). */
1555 for (delay
= delays
; delay
; delay
= delay
->next
)
1557 for (i
= 0; i
< XVECLEN (delay
->def
, 1); i
+= 3)
1559 condexp
= XVECEXP (delay
->def
, 1, i
);
1560 if (condexp
== 0) condexp
= false_rtx
;
1561 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1562 make_numeric_value (1), make_numeric_value (0));
1564 p
= attr_printf (sizeof ("*delay__") + MAX_DIGITS
*2, "*delay_%d_%d",
1566 make_internal_attr (p
, newexp
, 1);
1568 if (have_annul_true
)
1570 condexp
= XVECEXP (delay
->def
, 1, i
+ 1);
1571 if (condexp
== 0) condexp
= false_rtx
;
1572 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1573 make_numeric_value (1),
1574 make_numeric_value (0));
1575 p
= attr_printf (sizeof ("*annul_true__") + MAX_DIGITS
*2,
1576 "*annul_true_%d_%d", delay
->num
, i
/ 3);
1577 make_internal_attr (p
, newexp
, 1);
1580 if (have_annul_false
)
1582 condexp
= XVECEXP (delay
->def
, 1, i
+ 2);
1583 if (condexp
== 0) condexp
= false_rtx
;
1584 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1585 make_numeric_value (1),
1586 make_numeric_value (0));
1587 p
= attr_printf (sizeof ("*annul_false__") + MAX_DIGITS
*2,
1588 "*annul_false_%d_%d", delay
->num
, i
/ 3);
1589 make_internal_attr (p
, newexp
, 1);
1595 /* This function is given a left and right side expression and an operator.
1596 Each side is a conditional expression, each alternative of which has a
1597 numerical value. The function returns another conditional expression
1598 which, for every possible set of condition values, returns a value that is
1599 the operator applied to the values of the two sides.
1601 Since this is called early, it must also support IF_THEN_ELSE. */
1604 operate_exp (op
, left
, right
)
1608 int left_value
, right_value
;
1612 /* If left is a string, apply operator to it and the right side. */
1613 if (GET_CODE (left
) == CONST_STRING
)
1615 /* If right is also a string, just perform the operation. */
1616 if (GET_CODE (right
) == CONST_STRING
)
1618 left_value
= atoi (XSTR (left
, 0));
1619 right_value
= atoi (XSTR (right
, 0));
1623 i
= left_value
+ right_value
;
1627 i
= left_value
- right_value
;
1630 case POS_MINUS_OP
: /* The positive part of LEFT - RIGHT. */
1631 if (left_value
> right_value
)
1632 i
= left_value
- right_value
;
1638 i
= left_value
| right_value
;
1642 i
= left_value
== right_value
;
1646 i
= (left_value
<< (HOST_BITS_PER_INT
/ 2)) | right_value
;
1650 if (left_value
> right_value
)
1657 if (left_value
< right_value
)
1667 return make_numeric_value (i
);
1669 else if (GET_CODE (right
) == IF_THEN_ELSE
)
1671 /* Apply recursively to all values within. */
1672 rtx newleft
= operate_exp (op
, left
, XEXP (right
, 1));
1673 rtx newright
= operate_exp (op
, left
, XEXP (right
, 2));
1674 if (rtx_equal_p (newleft
, newright
))
1676 return attr_rtx (IF_THEN_ELSE
, XEXP (right
, 0), newleft
, newright
);
1678 else if (GET_CODE (right
) == COND
)
1683 newexp
= rtx_alloc (COND
);
1684 XVEC (newexp
, 0) = rtvec_alloc (XVECLEN (right
, 0));
1685 defval
= XEXP (newexp
, 1) = operate_exp (op
, left
, XEXP (right
, 1));
1687 for (i
= 0; i
< XVECLEN (right
, 0); i
+= 2)
1689 XVECEXP (newexp
, 0, i
) = XVECEXP (right
, 0, i
);
1690 XVECEXP (newexp
, 0, i
+ 1)
1691 = operate_exp (op
, left
, XVECEXP (right
, 0, i
+ 1));
1692 if (! rtx_equal_p (XVECEXP (newexp
, 0, i
+ 1),
1697 /* If the resulting cond is trivial (all alternatives
1698 give the same value), optimize it away. */
1701 obstack_free (rtl_obstack
, newexp
);
1702 return operate_exp (op
, left
, XEXP (right
, 1));
1705 /* If the result is the same as the RIGHT operand,
1707 if (rtx_equal_p (newexp
, right
))
1709 obstack_free (rtl_obstack
, newexp
);
1716 fatal ("Badly formed attribute value");
1719 /* Otherwise, do recursion the other way. */
1720 else if (GET_CODE (left
) == IF_THEN_ELSE
)
1722 rtx newleft
= operate_exp (op
, XEXP (left
, 1), right
);
1723 rtx newright
= operate_exp (op
, XEXP (left
, 2), right
);
1724 if (rtx_equal_p (newleft
, newright
))
1726 return attr_rtx (IF_THEN_ELSE
, XEXP (left
, 0), newleft
, newright
);
1728 else if (GET_CODE (left
) == COND
)
1733 newexp
= rtx_alloc (COND
);
1734 XVEC (newexp
, 0) = rtvec_alloc (XVECLEN (left
, 0));
1735 defval
= XEXP (newexp
, 1) = operate_exp (op
, XEXP (left
, 1), right
);
1737 for (i
= 0; i
< XVECLEN (left
, 0); i
+= 2)
1739 XVECEXP (newexp
, 0, i
) = XVECEXP (left
, 0, i
);
1740 XVECEXP (newexp
, 0, i
+ 1)
1741 = operate_exp (op
, XVECEXP (left
, 0, i
+ 1), right
);
1742 if (! rtx_equal_p (XVECEXP (newexp
, 0, i
+ 1),
1747 /* If the cond is trivial (all alternatives give the same value),
1748 optimize it away. */
1751 obstack_free (rtl_obstack
, newexp
);
1752 return operate_exp (op
, XEXP (left
, 1), right
);
1755 /* If the result is the same as the LEFT operand,
1757 if (rtx_equal_p (newexp
, left
))
1759 obstack_free (rtl_obstack
, newexp
);
1767 fatal ("Badly formed attribute value.");
1772 /* Once all attributes and DEFINE_FUNCTION_UNITs have been read, we
1773 construct a number of attributes.
1775 The first produces a function `function_units_used' which is given an
1776 insn and produces an encoding showing which function units are required
1777 for the execution of that insn. If the value is non-negative, the insn
1778 uses that unit; otherwise, the value is a one's compliment mask of units
1781 The second produces a function `result_ready_cost' which is used to
1782 determine the time that the result of an insn will be ready and hence
1783 a worst-case schedule.
1785 Both of these produce quite complex expressions which are then set as the
1786 default value of internal attributes. Normal attribute simplification
1787 should produce reasonable expressions.
1789 For each unit, a `<name>_unit_ready_cost' function will take an
1790 insn and give the delay until that unit will be ready with the result
1791 and a `<name>_unit_conflict_cost' function is given an insn already
1792 executing on the unit and a candidate to execute and will give the
1793 cost from the time the executing insn started until the candidate
1794 can start (ignore limitations on the number of simultaneous insns).
1796 For each unit, a `<name>_unit_blockage' function is given an insn
1797 already executing on the unit and a candidate to execute and will
1798 give the delay incurred due to function unit conflicts. The range of
1799 blockage cost values for a given executing insn is given by the
1800 `<name>_unit_blockage_range' function. These values are encoded in
1801 an int where the upper half gives the minimum value and the lower
1802 half gives the maximum value. */
1807 struct function_unit
*unit
, **unit_num
;
1808 struct function_unit_op
*op
, **op_array
, ***unit_ops
;
1813 int i
, j
, u
, num
, nvalues
;
1815 /* Rebuild the condition for the unit to share the RTL expressions.
1816 Sharing is required by simplify_by_exploding. Build the issue delay
1817 expressions. Validate the expressions we were given for the conditions
1818 and conflict vector. Then make attributes for use in the conflict
1821 for (unit
= units
; unit
; unit
= unit
->next
)
1823 unit
->condexp
= check_attr_test (unit
->condexp
, 0);
1825 for (op
= unit
->ops
; op
; op
= op
->next
)
1827 rtx issue_delay
= make_numeric_value (op
->issue_delay
);
1828 rtx issue_exp
= issue_delay
;
1830 /* Build, validate, and simplify the issue delay expression. */
1831 if (op
->conflict_exp
!= true_rtx
)
1832 issue_exp
= attr_rtx (IF_THEN_ELSE
, op
->conflict_exp
,
1833 issue_exp
, make_numeric_value (0));
1834 issue_exp
= check_attr_value (make_canonical (NULL_ATTR
,
1837 issue_exp
= simplify_knowing (issue_exp
, unit
->condexp
);
1838 op
->issue_exp
= issue_exp
;
1840 /* Make an attribute for use in the conflict function if needed. */
1841 unit
->needs_conflict_function
= (unit
->issue_delay
.min
1842 != unit
->issue_delay
.max
);
1843 if (unit
->needs_conflict_function
)
1845 str
= attr_printf (strlen (unit
->name
) + sizeof ("*_cost_") + MAX_DIGITS
,
1846 "*%s_cost_%d", unit
->name
, op
->num
);
1847 make_internal_attr (str
, issue_exp
, 1);
1850 /* Validate the condition. */
1851 op
->condexp
= check_attr_test (op
->condexp
, 0);
1855 /* Compute the mask of function units used. Initially, the unitsmask is
1856 zero. Set up a conditional to compute each unit's contribution. */
1857 unitsmask
= make_numeric_value (0);
1858 newexp
= rtx_alloc (IF_THEN_ELSE
);
1859 XEXP (newexp
, 2) = make_numeric_value (0);
1861 /* Merge each function unit into the unit mask attributes. */
1862 for (unit
= units
; unit
; unit
= unit
->next
)
1864 XEXP (newexp
, 0) = unit
->condexp
;
1865 XEXP (newexp
, 1) = make_numeric_value (1 << unit
->num
);
1866 unitsmask
= operate_exp (OR_OP
, unitsmask
, newexp
);
1869 /* Simplify the unit mask expression, encode it, and make an attribute
1870 for the function_units_used function. */
1871 unitsmask
= simplify_by_exploding (unitsmask
);
1872 unitsmask
= encode_units_mask (unitsmask
);
1873 make_internal_attr ("*function_units_used", unitsmask
, 2);
1875 /* Create an array of ops for each unit. Add an extra unit for the
1876 result_ready_cost function that has the ops of all other units. */
1877 unit_ops
= (struct function_unit_op
***)
1878 alloca ((num_units
+ 1) * sizeof (struct function_unit_op
**));
1879 unit_num
= (struct function_unit
**)
1880 alloca ((num_units
+ 1) * sizeof (struct function_unit
*));
1882 unit_num
[num_units
] = unit
= (struct function_unit
*)
1883 alloca (sizeof (struct function_unit
));
1884 unit
->num
= num_units
;
1885 unit
->num_opclasses
= 0;
1887 for (unit
= units
; unit
; unit
= unit
->next
)
1889 unit_num
[num_units
]->num_opclasses
+= unit
->num_opclasses
;
1890 unit_num
[unit
->num
] = unit
;
1891 unit_ops
[unit
->num
] = op_array
= (struct function_unit_op
**)
1892 alloca (unit
->num_opclasses
* sizeof (struct function_unit_op
*));
1894 for (op
= unit
->ops
; op
; op
= op
->next
)
1895 op_array
[op
->num
] = op
;
1898 /* Compose the array of ops for the extra unit. */
1899 unit_ops
[num_units
] = op_array
= (struct function_unit_op
**)
1900 alloca (unit_num
[num_units
]->num_opclasses
1901 * sizeof (struct function_unit_op
*));
1903 for (unit
= units
, i
= 0; unit
; i
+= unit
->num_opclasses
, unit
= unit
->next
)
1904 bcopy ((char *) unit_ops
[unit
->num
], (char *) &op_array
[i
],
1905 unit
->num_opclasses
* sizeof (struct function_unit_op
*));
1907 /* Compute the ready cost function for each unit by computing the
1908 condition for each non-default value. */
1909 for (u
= 0; u
<= num_units
; u
++)
1915 op_array
= unit_ops
[unit
->num
];
1916 num
= unit
->num_opclasses
;
1918 /* Sort the array of ops into increasing ready cost order. */
1919 for (i
= 0; i
< num
; i
++)
1920 for (j
= num
- 1; j
> i
; j
--)
1921 if (op_array
[j
-1]->ready
< op_array
[j
]->ready
)
1924 op_array
[j
] = op_array
[j
-1];
1928 /* Determine how many distinct non-default ready cost values there
1929 are. We use a default ready cost value of 1. */
1930 nvalues
= 0; value
= 1;
1931 for (i
= num
- 1; i
>= 0; i
--)
1932 if (op_array
[i
]->ready
> value
)
1934 value
= op_array
[i
]->ready
;
1939 readycost
= make_numeric_value (1);
1942 /* Construct the ready cost expression as a COND of each value from
1943 the largest to the smallest. */
1944 readycost
= rtx_alloc (COND
);
1945 XVEC (readycost
, 0) = rtvec_alloc (nvalues
* 2);
1946 XEXP (readycost
, 1) = make_numeric_value (1);
1948 nvalues
= 0; orexp
= false_rtx
; value
= op_array
[0]->ready
;
1949 for (i
= 0; i
< num
; i
++)
1954 else if (op
->ready
== value
)
1955 orexp
= insert_right_side (IOR
, orexp
, op
->condexp
, -2, -2);
1958 XVECEXP (readycost
, 0, nvalues
* 2) = orexp
;
1959 XVECEXP (readycost
, 0, nvalues
* 2 + 1)
1960 = make_numeric_value (value
);
1963 orexp
= op
->condexp
;
1966 XVECEXP (readycost
, 0, nvalues
* 2) = orexp
;
1967 XVECEXP (readycost
, 0, nvalues
* 2 + 1) = make_numeric_value (value
);
1972 rtx max_blockage
= 0, min_blockage
= 0;
1974 /* Simplify the readycost expression by only considering insns
1975 that use the unit. */
1976 readycost
= simplify_knowing (readycost
, unit
->condexp
);
1978 /* Determine the blockage cost the executing insn (E) given
1979 the candidate insn (C). This is the maximum of the issue
1980 delay, the pipeline delay, and the simultaneity constraint.
1981 Each function_unit_op represents the characteristics of the
1982 candidate insn, so in the expressions below, C is a known
1983 term and E is an unknown term.
1985 We compute the blockage cost for each E for every possible C.
1986 Thus OP represents E, and READYCOST is a list of values for
1989 The issue delay function for C is op->issue_exp and is used to
1990 write the `<name>_unit_conflict_cost' function. Symbolicly
1991 this is "ISSUE-DELAY (E,C)".
1993 The pipeline delay results form the FIFO constraint on the
1994 function unit and is "READY-COST (E) + 1 - READY-COST (C)".
1996 The simultaneity constraint is based on how long it takes to
1997 fill the unit given the minimum issue delay. FILL-TIME is the
1998 constant "MIN (ISSUE-DELAY (*,*)) * (SIMULTANEITY - 1)", and
1999 the simultaneity constraint is "READY-COST (E) - FILL-TIME"
2000 if SIMULTANEITY is non-zero and zero otherwise.
2002 Thus, BLOCKAGE (E,C) when SIMULTANEITY is zero is
2004 MAX (ISSUE-DELAY (E,C),
2005 READY-COST (E) - (READY-COST (C) - 1))
2009 MAX (ISSUE-DELAY (E,C),
2010 READY-COST (E) - (READY-COST (C) - 1),
2011 READY-COST (E) - FILL-TIME)
2013 The `<name>_unit_blockage' function is computed by determining
2014 this value for each candidate insn. As these values are
2015 computed, we also compute the upper and lower bounds for
2016 BLOCKAGE (E,*). These are combined to form the function
2017 `<name>_unit_blockage_range'. Finally, the maximum blockage
2018 cost, MAX (BLOCKAGE (*,*)), is computed. */
2020 for (op
= unit
->ops
; op
; op
= op
->next
)
2022 rtx blockage
= operate_exp (POS_MINUS_OP
, readycost
,
2023 make_numeric_value (1));
2025 if (unit
->simultaneity
!= 0)
2027 rtx filltime
= make_numeric_value ((unit
->simultaneity
- 1)
2028 * unit
->issue_delay
.min
);
2029 blockage
= operate_exp (MIN_OP
, blockage
, filltime
);
2032 blockage
= operate_exp (POS_MINUS_OP
,
2033 make_numeric_value (op
->ready
),
2036 blockage
= operate_exp (MAX_OP
, blockage
, op
->issue_exp
);
2037 blockage
= simplify_knowing (blockage
, unit
->condexp
);
2039 /* Add this op's contribution to MAX (BLOCKAGE (E,*)) and
2040 MIN (BLOCKAGE (E,*)). */
2041 if (max_blockage
== 0)
2042 max_blockage
= min_blockage
= blockage
;
2046 = simplify_knowing (operate_exp (MAX_OP
, max_blockage
,
2050 = simplify_knowing (operate_exp (MIN_OP
, min_blockage
,
2055 /* Make an attribute for use in the blockage function. */
2056 str
= attr_printf (strlen (unit
->name
) + sizeof ("*_block_") + MAX_DIGITS
,
2057 "*%s_block_%d", unit
->name
, op
->num
);
2058 make_internal_attr (str
, blockage
, 1);
2061 /* Record MAX (BLOCKAGE (*,*)). */
2062 unit
->max_blockage
= max_attr_value (max_blockage
);
2064 /* See if the upper and lower bounds of BLOCKAGE (E,*) are the
2065 same. If so, the blockage function carries no additional
2066 information and is not written. */
2067 newexp
= operate_exp (EQ_OP
, max_blockage
, min_blockage
);
2068 newexp
= simplify_knowing (newexp
, unit
->condexp
);
2069 unit
->needs_blockage_function
2070 = (GET_CODE (newexp
) != CONST_STRING
2071 || atoi (XSTR (newexp
, 0)) != 1);
2073 /* If the all values of BLOCKAGE (E,C) have the same value,
2074 neither blockage function is written. */
2075 unit
->needs_range_function
2076 = (unit
->needs_blockage_function
2077 || GET_CODE (max_blockage
) != CONST_STRING
);
2079 if (unit
->needs_range_function
)
2081 /* Compute the blockage range function and make an attribute
2082 for writing its value. */
2083 newexp
= operate_exp (RANGE_OP
, min_blockage
, max_blockage
);
2084 newexp
= simplify_knowing (newexp
, unit
->condexp
);
2086 str
= attr_printf (strlen (unit
->name
) + sizeof ("*_unit_blockage_range"),
2087 "*%s_unit_blockage_range", unit
->name
);
2088 make_internal_attr (str
, newexp
, 4);
2091 str
= attr_printf (strlen (unit
->name
) + sizeof ("*_unit_ready_cost"),
2092 "*%s_unit_ready_cost", unit
->name
);
2095 str
= "*result_ready_cost";
2097 /* Make an attribute for the ready_cost function. Simplifying
2098 further with simplify_by_exploding doesn't win. */
2099 make_internal_attr (str
, readycost
, 0);
2102 /* For each unit that requires a conflict cost function, make an attribute
2103 that maps insns to the operation number. */
2104 for (unit
= units
; unit
; unit
= unit
->next
)
2108 if (! unit
->needs_conflict_function
2109 && ! unit
->needs_blockage_function
)
2112 caseexp
= rtx_alloc (COND
);
2113 XVEC (caseexp
, 0) = rtvec_alloc ((unit
->num_opclasses
- 1) * 2);
2115 for (op
= unit
->ops
; op
; op
= op
->next
)
2117 /* Make our adjustment to the COND being computed. If we are the
2118 last operation class, place our values into the default of the
2120 if (op
->num
== unit
->num_opclasses
- 1)
2122 XEXP (caseexp
, 1) = make_numeric_value (op
->num
);
2126 XVECEXP (caseexp
, 0, op
->num
* 2) = op
->condexp
;
2127 XVECEXP (caseexp
, 0, op
->num
* 2 + 1)
2128 = make_numeric_value (op
->num
);
2132 /* Simplifying caseexp with simplify_by_exploding doesn't win. */
2133 str
= attr_printf (strlen (unit
->name
) + sizeof ("*_cases"),
2134 "*%s_cases", unit
->name
);
2135 make_internal_attr (str
, caseexp
, 1);
2139 /* Simplify EXP given KNOWN_TRUE. */
2142 simplify_knowing (exp
, known_true
)
2143 rtx exp
, known_true
;
2145 if (GET_CODE (exp
) != CONST_STRING
)
2147 exp
= attr_rtx (IF_THEN_ELSE
, known_true
, exp
,
2148 make_numeric_value (max_attr_value (exp
)));
2149 exp
= simplify_by_exploding (exp
);
2154 /* Translate the CONST_STRING expressions in X to change the encoding of
2155 value. On input, the value is a bitmask with a one bit for each unit
2156 used; on output, the value is the unit number (zero based) if one
2157 and only one unit is used or the one's compliment of the bitmask. */
2160 encode_units_mask (x
)
2165 register enum rtx_code code
;
2168 code
= GET_CODE (x
);
2173 i
= atoi (XSTR (x
, 0));
2175 abort (); /* The sign bit encodes a one's compliment mask. */
2176 else if (i
!= 0 && i
== (i
& -i
))
2177 /* Only one bit is set, so yield that unit number. */
2178 for (j
= 0; (i
>>= 1) != 0; j
++)
2182 return attr_rtx (CONST_STRING
, attr_printf (MAX_DIGITS
, "%d", j
));
2199 /* Compare the elements. If any pair of corresponding elements
2200 fail to match, return 0 for the whole things. */
2202 fmt
= GET_RTX_FORMAT (code
);
2203 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
2209 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
2210 XVECEXP (x
, i
, j
) = encode_units_mask (XVECEXP (x
, i
, j
));
2214 XEXP (x
, i
) = encode_units_mask (XEXP (x
, i
));
2221 /* Once all attributes and insns have been read and checked, we construct for
2222 each attribute value a list of all the insns that have that value for
2227 struct attr_desc
*attr
;
2229 struct attr_value
*av
;
2230 struct insn_ent
*ie
;
2231 struct insn_def
*id
;
2235 /* Don't fill constant attributes. The value is independent of
2236 any particular insn. */
2240 for (id
= defs
; id
; id
= id
->next
)
2242 /* If no value is specified for this insn for this attribute, use the
2245 if (XVEC (id
->def
, id
->vec_idx
))
2246 for (i
= 0; i
< XVECLEN (id
->def
, id
->vec_idx
); i
++)
2247 if (! strcmp (XSTR (XEXP (XVECEXP (id
->def
, id
->vec_idx
, i
), 0), 0),
2249 value
= XEXP (XVECEXP (id
->def
, id
->vec_idx
, i
), 1);
2252 av
= attr
->default_val
;
2254 av
= get_attr_value (value
, attr
, id
->insn_code
);
2256 ie
= (struct insn_ent
*) oballoc (sizeof (struct insn_ent
));
2257 ie
->insn_code
= id
->insn_code
;
2258 ie
->insn_index
= id
->insn_code
;
2259 insert_insn_ent (av
, ie
);
2263 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
2264 test that checks relative positions of insns (uses MATCH_DUP or PC).
2265 If so, replace it with what is obtained by passing the expression to
2266 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
2267 recursively on each value (including the default value). Otherwise,
2268 return the value returned by NO_ADDRESS_FN applied to EXP. */
2271 substitute_address (exp
, no_address_fn
, address_fn
)
2273 rtx (*no_address_fn
) ();
2274 rtx (*address_fn
) ();
2279 if (GET_CODE (exp
) == COND
)
2281 /* See if any tests use addresses. */
2283 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
2284 walk_attr_value (XVECEXP (exp
, 0, i
));
2287 return (*address_fn
) (exp
);
2289 /* Make a new copy of this COND, replacing each element. */
2290 newexp
= rtx_alloc (COND
);
2291 XVEC (newexp
, 0) = rtvec_alloc (XVECLEN (exp
, 0));
2292 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
2294 XVECEXP (newexp
, 0, i
) = XVECEXP (exp
, 0, i
);
2295 XVECEXP (newexp
, 0, i
+ 1)
2296 = substitute_address (XVECEXP (exp
, 0, i
+ 1),
2297 no_address_fn
, address_fn
);
2300 XEXP (newexp
, 1) = substitute_address (XEXP (exp
, 1),
2301 no_address_fn
, address_fn
);
2306 else if (GET_CODE (exp
) == IF_THEN_ELSE
)
2309 walk_attr_value (XEXP (exp
, 0));
2311 return (*address_fn
) (exp
);
2313 return attr_rtx (IF_THEN_ELSE
,
2314 substitute_address (XEXP (exp
, 0),
2315 no_address_fn
, address_fn
),
2316 substitute_address (XEXP (exp
, 1),
2317 no_address_fn
, address_fn
),
2318 substitute_address (XEXP (exp
, 2),
2319 no_address_fn
, address_fn
));
2322 return (*no_address_fn
) (exp
);
2325 /* Make new attributes from the `length' attribute. The following are made,
2326 each corresponding to a function called from `shorten_branches' or
2329 *insn_default_length This is the length of the insn to be returned
2330 by `get_attr_length' before `shorten_branches'
2331 has been called. In each case where the length
2332 depends on relative addresses, the largest
2333 possible is used. This routine is also used
2334 to compute the initial size of the insn.
2336 *insn_variable_length_p This returns 1 if the insn's length depends
2337 on relative addresses, zero otherwise.
2339 *insn_current_length This is only called when it is known that the
2340 insn has a variable length and returns the
2341 current length, based on relative addresses.
2345 make_length_attrs ()
2347 static char *new_names
[] = {"*insn_default_length",
2348 "*insn_variable_length_p",
2349 "*insn_current_length"};
2350 static rtx (*no_address_fn
[]) PROTO((rtx
)) = {identity_fn
, zero_fn
, zero_fn
};
2351 static rtx (*address_fn
[]) PROTO((rtx
)) = {max_fn
, one_fn
, identity_fn
};
2353 struct attr_desc
*length_attr
, *new_attr
;
2354 struct attr_value
*av
, *new_av
;
2355 struct insn_ent
*ie
, *new_ie
;
2357 /* See if length attribute is defined. If so, it must be numeric. Make
2358 it special so we don't output anything for it. */
2359 length_attr
= find_attr ("length", 0);
2360 if (length_attr
== 0)
2363 if (! length_attr
->is_numeric
)
2364 fatal ("length attribute must be numeric.");
2366 length_attr
->is_const
= 0;
2367 length_attr
->is_special
= 1;
2369 /* Make each new attribute, in turn. */
2370 for (i
= 0; i
< sizeof new_names
/ sizeof new_names
[0]; i
++)
2372 make_internal_attr (new_names
[i
],
2373 substitute_address (length_attr
->default_val
->value
,
2374 no_address_fn
[i
], address_fn
[i
]),
2376 new_attr
= find_attr (new_names
[i
], 0);
2377 for (av
= length_attr
->first_value
; av
; av
= av
->next
)
2378 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2380 new_av
= get_attr_value (substitute_address (av
->value
,
2383 new_attr
, ie
->insn_code
);
2384 new_ie
= (struct insn_ent
*) oballoc (sizeof (struct insn_ent
));
2385 new_ie
->insn_code
= ie
->insn_code
;
2386 new_ie
->insn_index
= ie
->insn_index
;
2387 insert_insn_ent (new_av
, new_ie
);
2392 /* Utility functions called from above routine. */
2405 return make_numeric_value (0);
2412 return make_numeric_value (1);
2419 return make_numeric_value (max_attr_value (exp
));
2422 /* Take a COND expression and see if any of the conditions in it can be
2423 simplified. If any are known true or known false for the particular insn
2424 code, the COND can be further simplified.
2426 Also call ourselves on any COND operations that are values of this COND.
2428 We do not modify EXP; rather, we make and return a new rtx. */
2431 simplify_cond (exp
, insn_code
, insn_index
)
2433 int insn_code
, insn_index
;
2436 /* We store the desired contents here,
2437 then build a new expression if they don't match EXP. */
2438 rtx defval
= XEXP (exp
, 1);
2439 rtx new_defval
= XEXP (exp
, 1);
2440 int len
= XVECLEN (exp
, 0);
2441 rtunion
*tests
= (rtunion
*) alloca (len
* sizeof (rtunion
));
2445 /* This lets us free all storage allocated below, if appropriate. */
2446 first_spacer
= (char *) obstack_finish (rtl_obstack
);
2448 bcopy ((char *) XVEC (exp
, 0)->elem
, (char *) tests
, len
* sizeof (rtunion
));
2450 /* See if default value needs simplification. */
2451 if (GET_CODE (defval
) == COND
)
2452 new_defval
= simplify_cond (defval
, insn_code
, insn_index
);
2454 /* Simplify the subexpressions, and see what tests we can get rid of. */
2456 for (i
= 0; i
< len
; i
+= 2)
2458 rtx newtest
, newval
;
2460 /* Simplify this test. */
2461 newtest
= SIMPLIFY_TEST_EXP (tests
[i
].rtx
, insn_code
, insn_index
);
2462 tests
[i
].rtx
= newtest
;
2464 newval
= tests
[i
+ 1].rtx
;
2465 /* See if this value may need simplification. */
2466 if (GET_CODE (newval
) == COND
)
2467 newval
= simplify_cond (newval
, insn_code
, insn_index
);
2469 /* Look for ways to delete or combine this test. */
2470 if (newtest
== true_rtx
)
2472 /* If test is true, make this value the default
2473 and discard this + any following tests. */
2475 defval
= tests
[i
+ 1].rtx
;
2476 new_defval
= newval
;
2479 else if (newtest
== false_rtx
)
2481 /* If test is false, discard it and its value. */
2482 for (j
= i
; j
< len
- 2; j
++)
2483 tests
[j
].rtx
= tests
[j
+ 2].rtx
;
2487 else if (i
> 0 && attr_equal_p (newval
, tests
[i
- 1].rtx
))
2489 /* If this value and the value for the prev test are the same,
2493 = insert_right_side (IOR
, tests
[i
- 2].rtx
, newtest
,
2494 insn_code
, insn_index
);
2496 /* Delete this test/value. */
2497 for (j
= i
; j
< len
- 2; j
++)
2498 tests
[j
].rtx
= tests
[j
+ 2].rtx
;
2503 tests
[i
+ 1].rtx
= newval
;
2506 /* If the last test in a COND has the same value
2507 as the default value, that test isn't needed. */
2509 while (len
> 0 && attr_equal_p (tests
[len
- 1].rtx
, new_defval
))
2512 /* See if we changed anything. */
2513 if (len
!= XVECLEN (exp
, 0) || new_defval
!= XEXP (exp
, 1))
2516 for (i
= 0; i
< len
; i
++)
2517 if (! attr_equal_p (tests
[i
].rtx
, XVECEXP (exp
, 0, i
)))
2525 obstack_free (rtl_obstack
, first_spacer
);
2526 if (GET_CODE (defval
) == COND
)
2527 return simplify_cond (defval
, insn_code
, insn_index
);
2532 obstack_free (rtl_obstack
, first_spacer
);
2537 rtx newexp
= rtx_alloc (COND
);
2539 XVEC (newexp
, 0) = rtvec_alloc (len
);
2540 bcopy ((char *) tests
, (char *) XVEC (newexp
, 0)->elem
,
2541 len
* sizeof (rtunion
));
2542 XEXP (newexp
, 1) = new_defval
;
2547 /* Remove an insn entry from an attribute value. */
2550 remove_insn_ent (av
, ie
)
2551 struct attr_value
*av
;
2552 struct insn_ent
*ie
;
2554 struct insn_ent
*previe
;
2556 if (av
->first_insn
== ie
)
2557 av
->first_insn
= ie
->next
;
2560 for (previe
= av
->first_insn
; previe
->next
!= ie
; previe
= previe
->next
)
2562 previe
->next
= ie
->next
;
2566 if (ie
->insn_code
== -1)
2567 av
->has_asm_insn
= 0;
2572 /* Insert an insn entry in an attribute value list. */
2575 insert_insn_ent (av
, ie
)
2576 struct attr_value
*av
;
2577 struct insn_ent
*ie
;
2579 ie
->next
= av
->first_insn
;
2580 av
->first_insn
= ie
;
2582 if (ie
->insn_code
== -1)
2583 av
->has_asm_insn
= 1;
2588 /* This is a utility routine to take an expression that is a tree of either
2589 AND or IOR expressions and insert a new term. The new term will be
2590 inserted at the right side of the first node whose code does not match
2591 the root. A new node will be created with the root's code. Its left
2592 side will be the old right side and its right side will be the new
2595 If the `term' is itself a tree, all its leaves will be inserted. */
2598 insert_right_side (code
, exp
, term
, insn_code
, insn_index
)
2602 int insn_code
, insn_index
;
2606 /* Avoid consing in some special cases. */
2607 if (code
== AND
&& term
== true_rtx
)
2609 if (code
== AND
&& term
== false_rtx
)
2611 if (code
== AND
&& exp
== true_rtx
)
2613 if (code
== AND
&& exp
== false_rtx
)
2615 if (code
== IOR
&& term
== true_rtx
)
2617 if (code
== IOR
&& term
== false_rtx
)
2619 if (code
== IOR
&& exp
== true_rtx
)
2621 if (code
== IOR
&& exp
== false_rtx
)
2623 if (attr_equal_p (exp
, term
))
2626 if (GET_CODE (term
) == code
)
2628 exp
= insert_right_side (code
, exp
, XEXP (term
, 0),
2629 insn_code
, insn_index
);
2630 exp
= insert_right_side (code
, exp
, XEXP (term
, 1),
2631 insn_code
, insn_index
);
2636 if (GET_CODE (exp
) == code
)
2638 rtx
new = insert_right_side (code
, XEXP (exp
, 1),
2639 term
, insn_code
, insn_index
);
2640 if (new != XEXP (exp
, 1))
2641 /* Make a copy of this expression and call recursively. */
2642 newexp
= attr_rtx (code
, XEXP (exp
, 0), new);
2648 /* Insert the new term. */
2649 newexp
= attr_rtx (code
, exp
, term
);
2652 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2655 /* If we have an expression which AND's a bunch of
2656 (not (eq_attrq "alternative" "n"))
2657 terms, we may have covered all or all but one of the possible alternatives.
2658 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
2660 This routine is passed an expression and either AND or IOR. It returns a
2661 bitmask indicating which alternatives are mentioned within EXP. */
2664 compute_alternative_mask (exp
, code
)
2669 if (GET_CODE (exp
) == code
)
2670 return compute_alternative_mask (XEXP (exp
, 0), code
)
2671 | compute_alternative_mask (XEXP (exp
, 1), code
);
2673 else if (code
== AND
&& GET_CODE (exp
) == NOT
2674 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
2675 && XSTR (XEXP (exp
, 0), 0) == alternative_name
)
2676 string
= XSTR (XEXP (exp
, 0), 1);
2678 else if (code
== IOR
&& GET_CODE (exp
) == EQ_ATTR
2679 && XSTR (exp
, 0) == alternative_name
)
2680 string
= XSTR (exp
, 1);
2686 return 1 << (string
[0] - '0');
2687 return 1 << atoi (string
);
2690 /* Given I, a single-bit mask, return RTX to compare the `alternative'
2691 attribute with the value represented by that bit. */
2694 make_alternative_compare (mask
)
2701 for (i
= 0; (mask
& (1 << i
)) == 0; i
++)
2704 newexp
= attr_rtx (EQ_ATTR
, alternative_name
, attr_numeral (i
));
2705 RTX_UNCHANGING_P (newexp
) = 1;
2710 /* If we are processing an (eq_attr "attr" "value") test, we find the value
2711 of "attr" for this insn code. From that value, we can compute a test
2712 showing when the EQ_ATTR will be true. This routine performs that
2713 computation. If a test condition involves an address, we leave the EQ_ATTR
2714 intact because addresses are only valid for the `length' attribute.
2716 EXP is the EQ_ATTR expression and VALUE is the value of that attribute
2717 for the insn corresponding to INSN_CODE and INSN_INDEX. */
2720 evaluate_eq_attr (exp
, value
, insn_code
, insn_index
)
2723 int insn_code
, insn_index
;
2730 if (GET_CODE (value
) == CONST_STRING
)
2732 if (! strcmp (XSTR (value
, 0), XSTR (exp
, 1)))
2737 else if (GET_CODE (value
) == COND
)
2739 /* We construct an IOR of all the cases for which the requested attribute
2740 value is present. Since we start with FALSE, if it is not present,
2741 FALSE will be returned.
2743 Each case is the AND of the NOT's of the previous conditions with the
2744 current condition; in the default case the current condition is TRUE.
2746 For each possible COND value, call ourselves recursively.
2748 The extra TRUE and FALSE expressions will be eliminated by another
2749 call to the simplification routine. */
2754 if (current_alternative_string
)
2755 clear_struct_flag (value
);
2757 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
2759 rtx
this = SIMPLIFY_TEST_EXP (XVECEXP (value
, 0, i
),
2760 insn_code
, insn_index
);
2762 SIMPLIFY_ALTERNATIVE (this);
2764 right
= insert_right_side (AND
, andexp
, this,
2765 insn_code
, insn_index
);
2766 right
= insert_right_side (AND
, right
,
2767 evaluate_eq_attr (exp
,
2770 insn_code
, insn_index
),
2771 insn_code
, insn_index
);
2772 orexp
= insert_right_side (IOR
, orexp
, right
,
2773 insn_code
, insn_index
);
2775 /* Add this condition into the AND expression. */
2776 newexp
= attr_rtx (NOT
, this);
2777 andexp
= insert_right_side (AND
, andexp
, newexp
,
2778 insn_code
, insn_index
);
2781 /* Handle the default case. */
2782 right
= insert_right_side (AND
, andexp
,
2783 evaluate_eq_attr (exp
, XEXP (value
, 1),
2784 insn_code
, insn_index
),
2785 insn_code
, insn_index
);
2786 newexp
= insert_right_side (IOR
, orexp
, right
, insn_code
, insn_index
);
2791 /* If uses an address, must return original expression. But set the
2792 RTX_UNCHANGING_P bit so we don't try to simplify it again. */
2795 walk_attr_value (newexp
);
2799 /* This had `&& current_alternative_string', which seems to be wrong. */
2800 if (! RTX_UNCHANGING_P (exp
))
2801 return copy_rtx_unchanging (exp
);
2808 /* This routine is called when an AND of a term with a tree of AND's is
2809 encountered. If the term or its complement is present in the tree, it
2810 can be replaced with TRUE or FALSE, respectively.
2812 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2813 be true and hence are complementary.
2815 There is one special case: If we see
2816 (and (not (eq_attr "att" "v1"))
2817 (eq_attr "att" "v2"))
2818 this can be replaced by (eq_attr "att" "v2"). To do this we need to
2819 replace the term, not anything in the AND tree. So we pass a pointer to
2823 simplify_and_tree (exp
, pterm
, insn_code
, insn_index
)
2826 int insn_code
, insn_index
;
2831 int left_eliminates_term
, right_eliminates_term
;
2833 if (GET_CODE (exp
) == AND
)
2835 left
= simplify_and_tree (XEXP (exp
, 0), pterm
, insn_code
, insn_index
);
2836 right
= simplify_and_tree (XEXP (exp
, 1), pterm
, insn_code
, insn_index
);
2837 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2839 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
2841 exp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2845 else if (GET_CODE (exp
) == IOR
)
2847 /* For the IOR case, we do the same as above, except that we can
2848 only eliminate `term' if both sides of the IOR would do so. */
2850 left
= simplify_and_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
2851 left_eliminates_term
= (temp
== true_rtx
);
2854 right
= simplify_and_tree (XEXP (exp
, 1), &temp
, insn_code
, insn_index
);
2855 right_eliminates_term
= (temp
== true_rtx
);
2857 if (left_eliminates_term
&& right_eliminates_term
)
2860 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2862 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
2864 exp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2868 /* Check for simplifications. Do some extra checking here since this
2869 routine is called so many times. */
2874 else if (GET_CODE (exp
) == NOT
&& XEXP (exp
, 0) == *pterm
)
2877 else if (GET_CODE (*pterm
) == NOT
&& exp
== XEXP (*pterm
, 0))
2880 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == EQ_ATTR
)
2882 if (XSTR (exp
, 0) != XSTR (*pterm
, 0))
2885 if (! strcmp (XSTR (exp
, 1), XSTR (*pterm
, 1)))
2891 else if (GET_CODE (*pterm
) == EQ_ATTR
&& GET_CODE (exp
) == NOT
2892 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
)
2894 if (XSTR (*pterm
, 0) != XSTR (XEXP (exp
, 0), 0))
2897 if (! strcmp (XSTR (*pterm
, 1), XSTR (XEXP (exp
, 0), 1)))
2903 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == NOT
2904 && GET_CODE (XEXP (*pterm
, 0)) == EQ_ATTR
)
2906 if (XSTR (exp
, 0) != XSTR (XEXP (*pterm
, 0), 0))
2909 if (! strcmp (XSTR (exp
, 1), XSTR (XEXP (*pterm
, 0), 1)))
2915 else if (GET_CODE (exp
) == NOT
&& GET_CODE (*pterm
) == NOT
)
2917 if (attr_equal_p (XEXP (exp
, 0), XEXP (*pterm
, 0)))
2921 else if (GET_CODE (exp
) == NOT
)
2923 if (attr_equal_p (XEXP (exp
, 0), *pterm
))
2927 else if (GET_CODE (*pterm
) == NOT
)
2929 if (attr_equal_p (XEXP (*pterm
, 0), exp
))
2933 else if (attr_equal_p (exp
, *pterm
))
2939 /* Similar to `simplify_and_tree', but for IOR trees. */
2942 simplify_or_tree (exp
, pterm
, insn_code
, insn_index
)
2945 int insn_code
, insn_index
;
2950 int left_eliminates_term
, right_eliminates_term
;
2952 if (GET_CODE (exp
) == IOR
)
2954 left
= simplify_or_tree (XEXP (exp
, 0), pterm
, insn_code
, insn_index
);
2955 right
= simplify_or_tree (XEXP (exp
, 1), pterm
, insn_code
, insn_index
);
2956 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2958 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
2960 exp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2964 else if (GET_CODE (exp
) == AND
)
2966 /* For the AND case, we do the same as above, except that we can
2967 only eliminate `term' if both sides of the AND would do so. */
2969 left
= simplify_or_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
2970 left_eliminates_term
= (temp
== false_rtx
);
2973 right
= simplify_or_tree (XEXP (exp
, 1), &temp
, insn_code
, insn_index
);
2974 right_eliminates_term
= (temp
== false_rtx
);
2976 if (left_eliminates_term
&& right_eliminates_term
)
2979 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2981 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
2983 exp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2987 if (attr_equal_p (exp
, *pterm
))
2990 else if (GET_CODE (exp
) == NOT
&& attr_equal_p (XEXP (exp
, 0), *pterm
))
2993 else if (GET_CODE (*pterm
) == NOT
&& attr_equal_p (XEXP (*pterm
, 0), exp
))
2996 else if (GET_CODE (*pterm
) == EQ_ATTR
&& GET_CODE (exp
) == NOT
2997 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
2998 && XSTR (*pterm
, 0) == XSTR (XEXP (exp
, 0), 0))
3001 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == NOT
3002 && GET_CODE (XEXP (*pterm
, 0)) == EQ_ATTR
3003 && XSTR (exp
, 0) == XSTR (XEXP (*pterm
, 0), 0))
3009 /* Given an expression, see if it can be simplified for a particular insn
3010 code based on the values of other attributes being tested. This can
3011 eliminate nested get_attr_... calls.
3013 Note that if an endless recursion is specified in the patterns, the
3014 optimization will loop. However, it will do so in precisely the cases where
3015 an infinite recursion loop could occur during compilation. It's better that
3019 simplify_test_exp (exp
, insn_code
, insn_index
)
3021 int insn_code
, insn_index
;
3024 struct attr_desc
*attr
;
3025 struct attr_value
*av
;
3026 struct insn_ent
*ie
;
3029 char *spacer
= (char *) obstack_finish (rtl_obstack
);
3031 /* Don't re-simplify something we already simplified. */
3032 if (RTX_UNCHANGING_P (exp
) || MEM_IN_STRUCT_P (exp
))
3035 switch (GET_CODE (exp
))
3038 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
3039 SIMPLIFY_ALTERNATIVE (left
);
3040 if (left
== false_rtx
)
3042 obstack_free (rtl_obstack
, spacer
);
3045 right
= SIMPLIFY_TEST_EXP (XEXP (exp
, 1), insn_code
, insn_index
);
3046 SIMPLIFY_ALTERNATIVE (right
);
3047 if (left
== false_rtx
)
3049 obstack_free (rtl_obstack
, spacer
);
3053 /* If either side is an IOR and we have (eq_attr "alternative" ..")
3054 present on both sides, apply the distributive law since this will
3055 yield simplifications. */
3056 if ((GET_CODE (left
) == IOR
|| GET_CODE (right
) == IOR
)
3057 && compute_alternative_mask (left
, IOR
)
3058 && compute_alternative_mask (right
, IOR
))
3060 if (GET_CODE (left
) == IOR
)
3067 newexp
= attr_rtx (IOR
,
3068 attr_rtx (AND
, left
, XEXP (right
, 0)),
3069 attr_rtx (AND
, left
, XEXP (right
, 1)));
3071 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
3074 /* Try with the term on both sides. */
3075 right
= simplify_and_tree (right
, &left
, insn_code
, insn_index
);
3076 if (left
== XEXP (exp
, 0) && right
== XEXP (exp
, 1))
3077 left
= simplify_and_tree (left
, &right
, insn_code
, insn_index
);
3079 if (left
== false_rtx
|| right
== false_rtx
)
3081 obstack_free (rtl_obstack
, spacer
);
3084 else if (left
== true_rtx
)
3088 else if (right
== true_rtx
)
3092 /* See if all or all but one of the insn's alternatives are specified
3093 in this tree. Optimize if so. */
3095 else if (insn_code
>= 0
3096 && (GET_CODE (left
) == AND
3097 || (GET_CODE (left
) == NOT
3098 && GET_CODE (XEXP (left
, 0)) == EQ_ATTR
3099 && XSTR (XEXP (left
, 0), 0) == alternative_name
)
3100 || GET_CODE (right
) == AND
3101 || (GET_CODE (right
) == NOT
3102 && GET_CODE (XEXP (right
, 0)) == EQ_ATTR
3103 && XSTR (XEXP (right
, 0), 0) == alternative_name
)))
3105 i
= compute_alternative_mask (exp
, AND
);
3106 if (i
& ~insn_alternatives
[insn_code
])
3107 fatal ("Invalid alternative specified for pattern number %d",
3110 /* If all alternatives are excluded, this is false. */
3111 i
^= insn_alternatives
[insn_code
];
3114 else if ((i
& (i
- 1)) == 0 && insn_alternatives
[insn_code
] > 1)
3116 /* If just one excluded, AND a comparison with that one to the
3117 front of the tree. The others will be eliminated by
3118 optimization. We do not want to do this if the insn has one
3119 alternative and we have tested none of them! */
3120 left
= make_alternative_compare (i
);
3121 right
= simplify_and_tree (exp
, &left
, insn_code
, insn_index
);
3122 newexp
= attr_rtx (AND
, left
, right
);
3124 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
3128 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
3130 newexp
= attr_rtx (AND
, left
, right
);
3131 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
3136 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
3137 SIMPLIFY_ALTERNATIVE (left
);
3138 if (left
== true_rtx
)
3140 obstack_free (rtl_obstack
, spacer
);
3143 right
= SIMPLIFY_TEST_EXP (XEXP (exp
, 1), insn_code
, insn_index
);
3144 SIMPLIFY_ALTERNATIVE (right
);
3145 if (right
== true_rtx
)
3147 obstack_free (rtl_obstack
, spacer
);
3151 right
= simplify_or_tree (right
, &left
, insn_code
, insn_index
);
3152 if (left
== XEXP (exp
, 0) && right
== XEXP (exp
, 1))
3153 left
= simplify_or_tree (left
, &right
, insn_code
, insn_index
);
3155 if (right
== true_rtx
|| left
== true_rtx
)
3157 obstack_free (rtl_obstack
, spacer
);
3160 else if (left
== false_rtx
)
3164 else if (right
== false_rtx
)
3169 /* Test for simple cases where the distributive law is useful. I.e.,
3170 convert (ior (and (x) (y))
3176 else if (GET_CODE (left
) == AND
&& GET_CODE (right
) == AND
3177 && attr_equal_p (XEXP (left
, 0), XEXP (right
, 0)))
3179 newexp
= attr_rtx (IOR
, XEXP (left
, 1), XEXP (right
, 1));
3181 left
= XEXP (left
, 0);
3183 newexp
= attr_rtx (AND
, left
, right
);
3184 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
3187 /* See if all or all but one of the insn's alternatives are specified
3188 in this tree. Optimize if so. */
3190 else if (insn_code
>= 0
3191 && (GET_CODE (left
) == IOR
3192 || (GET_CODE (left
) == EQ_ATTR
3193 && XSTR (left
, 0) == alternative_name
)
3194 || GET_CODE (right
) == IOR
3195 || (GET_CODE (right
) == EQ_ATTR
3196 && XSTR (right
, 0) == alternative_name
)))
3198 i
= compute_alternative_mask (exp
, IOR
);
3199 if (i
& ~insn_alternatives
[insn_code
])
3200 fatal ("Invalid alternative specified for pattern number %d",
3203 /* If all alternatives are included, this is true. */
3204 i
^= insn_alternatives
[insn_code
];
3207 else if ((i
& (i
- 1)) == 0 && insn_alternatives
[insn_code
] > 1)
3209 /* If just one excluded, IOR a comparison with that one to the
3210 front of the tree. The others will be eliminated by
3211 optimization. We do not want to do this if the insn has one
3212 alternative and we have tested none of them! */
3213 left
= make_alternative_compare (i
);
3214 right
= simplify_and_tree (exp
, &left
, insn_code
, insn_index
);
3215 newexp
= attr_rtx (IOR
, attr_rtx (NOT
, left
), right
);
3217 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
3221 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
3223 newexp
= attr_rtx (IOR
, left
, right
);
3224 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
3229 if (GET_CODE (XEXP (exp
, 0)) == NOT
)
3231 left
= SIMPLIFY_TEST_EXP (XEXP (XEXP (exp
, 0), 0),
3232 insn_code
, insn_index
);
3233 SIMPLIFY_ALTERNATIVE (left
);
3237 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
3238 SIMPLIFY_ALTERNATIVE (left
);
3239 if (GET_CODE (left
) == NOT
)
3240 return XEXP (left
, 0);
3242 if (left
== false_rtx
)
3244 obstack_free (rtl_obstack
, spacer
);
3247 else if (left
== true_rtx
)
3249 obstack_free (rtl_obstack
, spacer
);
3253 /* Try to apply De`Morgan's laws. */
3254 else if (GET_CODE (left
) == IOR
)
3256 newexp
= attr_rtx (AND
,
3257 attr_rtx (NOT
, XEXP (left
, 0)),
3258 attr_rtx (NOT
, XEXP (left
, 1)));
3260 newexp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
3262 else if (GET_CODE (left
) == AND
)
3264 newexp
= attr_rtx (IOR
,
3265 attr_rtx (NOT
, XEXP (left
, 0)),
3266 attr_rtx (NOT
, XEXP (left
, 1)));
3268 newexp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
3270 else if (left
!= XEXP (exp
, 0))
3272 newexp
= attr_rtx (NOT
, left
);
3277 if (current_alternative_string
&& XSTR (exp
, 0) == alternative_name
)
3278 return (XSTR (exp
, 1) == current_alternative_string
3279 ? true_rtx
: false_rtx
);
3281 /* Look at the value for this insn code in the specified attribute.
3282 We normally can replace this comparison with the condition that
3283 would give this insn the values being tested for. */
3284 if (XSTR (exp
, 0) != alternative_name
3285 && (attr
= find_attr (XSTR (exp
, 0), 0)) != NULL
)
3286 for (av
= attr
->first_value
; av
; av
= av
->next
)
3287 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
3288 if (ie
->insn_code
== insn_code
)
3289 return evaluate_eq_attr (exp
, av
->value
, insn_code
, insn_index
);
3296 /* We have already simplified this expression. Simplifying it again
3297 won't buy anything unless we weren't given a valid insn code
3298 to process (i.e., we are canonicalizing something.). */
3299 if (insn_code
!= -2 /* Seems wrong: && current_alternative_string. */
3300 && ! RTX_UNCHANGING_P (newexp
))
3301 return copy_rtx_unchanging (newexp
);
3306 /* Optimize the attribute lists by seeing if we can determine conditional
3307 values from the known values of other attributes. This will save subroutine
3308 calls during the compilation. */
3313 struct attr_desc
*attr
;
3314 struct attr_value
*av
;
3315 struct insn_ent
*ie
;
3317 int something_changed
= 1;
3319 struct attr_value_list
{ struct attr_value
*av
;
3320 struct insn_ent
*ie
;
3321 struct attr_desc
* attr
;
3322 struct attr_value_list
*next
; };
3323 struct attr_value_list
**insn_code_values
;
3324 struct attr_value_list
*ivbuf
;
3325 struct attr_value_list
*iv
;
3327 /* For each insn code, make a list of all the insn_ent's for it,
3328 for all values for all attributes. */
3330 if (num_insn_ents
== 0)
3333 /* Make 2 extra elements, for "code" values -2 and -1. */
3335 = (struct attr_value_list
**) alloca ((insn_code_number
+ 2)
3336 * sizeof (struct attr_value_list
*));
3337 bzero ((char *) insn_code_values
,
3338 (insn_code_number
+ 2) * sizeof (struct attr_value_list
*));
3340 /* Offset the table address so we can index by -2 or -1. */
3341 insn_code_values
+= 2;
3343 /* Allocate the attr_value_list structures using xmalloc rather than
3344 alloca, because using alloca can overflow the maximum permitted
3345 stack limit on SPARC Lynx. */
3346 iv
= ivbuf
= ((struct attr_value_list
*)
3347 xmalloc (num_insn_ents
* sizeof (struct attr_value_list
)));
3349 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
3350 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
3351 for (av
= attr
->first_value
; av
; av
= av
->next
)
3352 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
3357 iv
->next
= insn_code_values
[ie
->insn_code
];
3358 insn_code_values
[ie
->insn_code
] = iv
;
3362 /* Sanity check on num_insn_ents. */
3363 if (iv
!= ivbuf
+ num_insn_ents
)
3366 /* Process one insn code at a time. */
3367 for (i
= -2; i
< insn_code_number
; i
++)
3369 /* Clear the MEM_IN_STRUCT_P flag everywhere relevant.
3370 We use it to mean "already simplified for this insn". */
3371 for (iv
= insn_code_values
[i
]; iv
; iv
= iv
->next
)
3372 clear_struct_flag (iv
->av
->value
);
3374 /* Loop until nothing changes for one iteration. */
3375 something_changed
= 1;
3376 while (something_changed
)
3378 something_changed
= 0;
3379 for (iv
= insn_code_values
[i
]; iv
; iv
= iv
->next
)
3381 struct obstack
*old
= rtl_obstack
;
3382 char *spacer
= (char *) obstack_finish (temp_obstack
);
3387 if (GET_CODE (av
->value
) != COND
)
3390 rtl_obstack
= temp_obstack
;
3391 #if 0 /* This was intended as a speed up, but it was slower. */
3392 if (insn_n_alternatives
[ie
->insn_code
] > 6
3393 && count_sub_rtxs (av
->value
, 200) >= 200)
3394 newexp
= simplify_by_alternatives (av
->value
, ie
->insn_code
,
3398 newexp
= simplify_cond (av
->value
, ie
->insn_code
,
3402 if (newexp
!= av
->value
)
3404 newexp
= attr_copy_rtx (newexp
);
3405 remove_insn_ent (av
, ie
);
3406 av
= get_attr_value (newexp
, attr
, ie
->insn_code
);
3408 insert_insn_ent (av
, ie
);
3409 something_changed
= 1;
3411 obstack_free (temp_obstack
, spacer
);
3421 simplify_by_alternatives (exp
, insn_code
, insn_index
)
3423 int insn_code
, insn_index
;
3426 int len
= insn_n_alternatives
[insn_code
];
3427 rtx newexp
= rtx_alloc (COND
);
3431 XVEC (newexp
, 0) = rtvec_alloc (len
* 2);
3433 /* It will not matter what value we use as the default value
3434 of the new COND, since that default will never be used.
3435 Choose something of the right type. */
3436 for (ultimate
= exp
; GET_CODE (ultimate
) == COND
;)
3437 ultimate
= XEXP (ultimate
, 1);
3438 XEXP (newexp
, 1) = ultimate
;
3440 for (i
= 0; i
< insn_n_alternatives
[insn_code
]; i
++)
3442 current_alternative_string
= attr_numeral (i
);
3443 XVECEXP (newexp
, 0, i
* 2) = make_alternative_compare (1 << i
);
3444 XVECEXP (newexp
, 0, i
* 2 + 1)
3445 = simplify_cond (exp
, insn_code
, insn_index
);
3448 current_alternative_string
= 0;
3449 return simplify_cond (newexp
, insn_code
, insn_index
);
3453 /* If EXP is a suitable expression, reorganize it by constructing an
3454 equivalent expression that is a COND with the tests being all combinations
3455 of attribute values and the values being simple constants. */
3458 simplify_by_exploding (exp
)
3461 rtx list
= 0, link
, condexp
, defval
;
3462 struct dimension
*space
;
3463 rtx
*condtest
, *condval
;
3464 int i
, j
, total
, ndim
= 0;
3465 int most_tests
, num_marks
, new_marks
;
3467 /* Locate all the EQ_ATTR expressions. */
3468 if (! find_and_mark_used_attributes (exp
, &list
, &ndim
) || ndim
== 0)
3470 unmark_used_attributes (list
, 0, 0);
3474 /* Create an attribute space from the list of used attributes. For each
3475 dimension in the attribute space, record the attribute, list of values
3476 used, and number of values used. Add members to the list of values to
3477 cover the domain of the attribute. This makes the expanded COND form
3478 order independent. */
3480 space
= (struct dimension
*) alloca (ndim
* sizeof (struct dimension
));
3483 for (ndim
= 0; list
; ndim
++)
3485 /* Pull the first attribute value from the list and record that
3486 attribute as another dimension in the attribute space. */
3487 char *name
= XSTR (XEXP (list
, 0), 0);
3490 if ((space
[ndim
].attr
= find_attr (name
, 0)) == 0
3491 || space
[ndim
].attr
->is_numeric
)
3493 unmark_used_attributes (list
, space
, ndim
);
3497 /* Add all remaining attribute values that refer to this attribute. */
3498 space
[ndim
].num_values
= 0;
3499 space
[ndim
].values
= 0;
3501 for (link
= list
; link
; link
= *prev
)
3502 if (! strcmp (XSTR (XEXP (link
, 0), 0), name
))
3504 space
[ndim
].num_values
++;
3505 *prev
= XEXP (link
, 1);
3506 XEXP (link
, 1) = space
[ndim
].values
;
3507 space
[ndim
].values
= link
;
3510 prev
= &XEXP (link
, 1);
3512 /* Add sufficient members to the list of values to make the list
3513 mutually exclusive and record the total size of the attribute
3515 total
*= add_values_to_cover (&space
[ndim
]);
3518 /* Sort the attribute space so that the attributes go from non-constant
3519 to constant and from most values to least values. */
3520 for (i
= 0; i
< ndim
; i
++)
3521 for (j
= ndim
- 1; j
> i
; j
--)
3522 if ((space
[j
-1].attr
->is_const
&& !space
[j
].attr
->is_const
)
3523 || space
[j
-1].num_values
< space
[j
].num_values
)
3525 struct dimension tmp
;
3527 space
[j
] = space
[j
-1];
3531 /* Establish the initial current value. */
3532 for (i
= 0; i
< ndim
; i
++)
3533 space
[i
].current_value
= space
[i
].values
;
3535 condtest
= (rtx
*) alloca (total
* sizeof (rtx
));
3536 condval
= (rtx
*) alloca (total
* sizeof (rtx
));
3538 /* Expand the tests and values by iterating over all values in the
3542 condtest
[i
] = test_for_current_value (space
, ndim
);
3543 condval
[i
] = simplify_with_current_value (exp
, space
, ndim
);
3544 if (! increment_current_value (space
, ndim
))
3550 /* We are now finished with the original expression. */
3551 unmark_used_attributes (0, space
, ndim
);
3553 /* Find the most used constant value and make that the default. */
3555 for (i
= num_marks
= 0; i
< total
; i
++)
3556 if (GET_CODE (condval
[i
]) == CONST_STRING
3557 && ! MEM_VOLATILE_P (condval
[i
]))
3559 /* Mark the unmarked constant value and count how many are marked. */
3560 MEM_VOLATILE_P (condval
[i
]) = 1;
3561 for (j
= new_marks
= 0; j
< total
; j
++)
3562 if (GET_CODE (condval
[j
]) == CONST_STRING
3563 && MEM_VOLATILE_P (condval
[j
]))
3565 if (new_marks
- num_marks
> most_tests
)
3567 most_tests
= new_marks
- num_marks
;
3568 defval
= condval
[i
];
3570 num_marks
= new_marks
;
3572 /* Clear all the marks. */
3573 for (i
= 0; i
< total
; i
++)
3574 MEM_VOLATILE_P (condval
[i
]) = 0;
3576 /* Give up if nothing is constant. */
3580 /* If all values are the default, use that. */
3581 if (total
== most_tests
)
3584 /* Make a COND with the most common constant value the default. (A more
3585 complex method where tests with the same value were combined didn't
3586 seem to improve things.) */
3587 condexp
= rtx_alloc (COND
);
3588 XVEC (condexp
, 0) = rtvec_alloc ((total
- most_tests
) * 2);
3589 XEXP (condexp
, 1) = defval
;
3590 for (i
= j
= 0; i
< total
; i
++)
3591 if (condval
[i
] != defval
)
3593 XVECEXP (condexp
, 0, 2 * j
) = condtest
[i
];
3594 XVECEXP (condexp
, 0, 2 * j
+ 1) = condval
[i
];
3601 /* Set the MEM_VOLATILE_P flag for all EQ_ATTR expressions in EXP and
3602 verify that EXP can be simplified to a constant term if all the EQ_ATTR
3603 tests have known value. */
3606 find_and_mark_used_attributes (exp
, terms
, nterms
)
3612 switch (GET_CODE (exp
))
3615 if (! MEM_VOLATILE_P (exp
))
3617 rtx link
= rtx_alloc (EXPR_LIST
);
3618 XEXP (link
, 0) = exp
;
3619 XEXP (link
, 1) = *terms
;
3622 MEM_VOLATILE_P (exp
) = 1;
3628 if (! find_and_mark_used_attributes (XEXP (exp
, 2), terms
, nterms
))
3632 if (! find_and_mark_used_attributes (XEXP (exp
, 1), terms
, nterms
))
3635 if (! find_and_mark_used_attributes (XEXP (exp
, 0), terms
, nterms
))
3640 for (i
= 0; i
< XVECLEN (exp
, 0); i
++)
3641 if (! find_and_mark_used_attributes (XVECEXP (exp
, 0, i
), terms
, nterms
))
3643 if (! find_and_mark_used_attributes (XEXP (exp
, 1), terms
, nterms
))
3652 /* Clear the MEM_VOLATILE_P flag in all EQ_ATTR expressions on LIST and
3653 in the values of the NDIM-dimensional attribute space SPACE. */
3656 unmark_used_attributes (list
, space
, ndim
)
3658 struct dimension
*space
;
3664 for (i
= 0; i
< ndim
; i
++)
3665 unmark_used_attributes (space
[i
].values
, 0, 0);
3667 for (link
= list
; link
; link
= XEXP (link
, 1))
3669 exp
= XEXP (link
, 0);
3670 if (GET_CODE (exp
) == EQ_ATTR
)
3671 MEM_VOLATILE_P (exp
) = 0;
3675 /* Update the attribute dimension DIM so that all values of the attribute
3676 are tested. Return the updated number of values. */
3679 add_values_to_cover (dim
)
3680 struct dimension
*dim
;
3682 struct attr_value
*av
;
3683 rtx exp
, link
, *prev
;
3686 for (av
= dim
->attr
->first_value
; av
; av
= av
->next
)
3687 if (GET_CODE (av
->value
) == CONST_STRING
)
3690 if (nalt
< dim
->num_values
)
3692 else if (nalt
== dim
->num_values
)
3694 else if (nalt
* 2 < dim
->num_values
* 3)
3696 /* Most all the values of the attribute are used, so add all the unused
3698 prev
= &dim
->values
;
3699 for (link
= dim
->values
; link
; link
= *prev
)
3700 prev
= &XEXP (link
, 1);
3702 for (av
= dim
->attr
->first_value
; av
; av
= av
->next
)
3703 if (GET_CODE (av
->value
) == CONST_STRING
)
3705 exp
= attr_eq (dim
->attr
->name
, XSTR (av
->value
, 0));
3706 if (MEM_VOLATILE_P (exp
))
3709 link
= rtx_alloc (EXPR_LIST
);
3710 XEXP (link
, 0) = exp
;
3713 prev
= &XEXP (link
, 1);
3715 dim
->num_values
= nalt
;
3719 rtx orexp
= false_rtx
;
3721 /* Very few values are used, so compute a mutually exclusive
3722 expression. (We could do this for numeric values if that becomes
3724 prev
= &dim
->values
;
3725 for (link
= dim
->values
; link
; link
= *prev
)
3727 orexp
= insert_right_side (IOR
, orexp
, XEXP (link
, 0), -2, -2);
3728 prev
= &XEXP (link
, 1);
3730 link
= rtx_alloc (EXPR_LIST
);
3731 XEXP (link
, 0) = attr_rtx (NOT
, orexp
);
3736 return dim
->num_values
;
3739 /* Increment the current value for the NDIM-dimensional attribute space SPACE
3740 and return FALSE if the increment overflowed. */
3743 increment_current_value (space
, ndim
)
3744 struct dimension
*space
;
3749 for (i
= ndim
- 1; i
>= 0; i
--)
3751 if ((space
[i
].current_value
= XEXP (space
[i
].current_value
, 1)) == 0)
3752 space
[i
].current_value
= space
[i
].values
;
3759 /* Construct an expression corresponding to the current value for the
3760 NDIM-dimensional attribute space SPACE. */
3763 test_for_current_value (space
, ndim
)
3764 struct dimension
*space
;
3770 for (i
= 0; i
< ndim
; i
++)
3771 exp
= insert_right_side (AND
, exp
, XEXP (space
[i
].current_value
, 0),
3777 /* Given the current value of the NDIM-dimensional attribute space SPACE,
3778 set the corresponding EQ_ATTR expressions to that value and reduce
3779 the expression EXP as much as possible. On input [and output], all
3780 known EQ_ATTR expressions are set to FALSE. */
3783 simplify_with_current_value (exp
, space
, ndim
)
3785 struct dimension
*space
;
3791 /* Mark each current value as TRUE. */
3792 for (i
= 0; i
< ndim
; i
++)
3794 x
= XEXP (space
[i
].current_value
, 0);
3795 if (GET_CODE (x
) == EQ_ATTR
)
3796 MEM_VOLATILE_P (x
) = 0;
3799 exp
= simplify_with_current_value_aux (exp
);
3801 /* Change each current value back to FALSE. */
3802 for (i
= 0; i
< ndim
; i
++)
3804 x
= XEXP (space
[i
].current_value
, 0);
3805 if (GET_CODE (x
) == EQ_ATTR
)
3806 MEM_VOLATILE_P (x
) = 1;
3812 /* Reduce the expression EXP based on the MEM_VOLATILE_P settings of
3813 all EQ_ATTR expressions. */
3816 simplify_with_current_value_aux (exp
)
3822 switch (GET_CODE (exp
))
3825 if (MEM_VOLATILE_P (exp
))
3833 cond
= simplify_with_current_value_aux (XEXP (exp
, 0));
3834 if (cond
== true_rtx
)
3835 return simplify_with_current_value_aux (XEXP (exp
, 1));
3836 else if (cond
== false_rtx
)
3837 return simplify_with_current_value_aux (XEXP (exp
, 2));
3839 return attr_rtx (IF_THEN_ELSE
, cond
,
3840 simplify_with_current_value_aux (XEXP (exp
, 1)),
3841 simplify_with_current_value_aux (XEXP (exp
, 2)));
3844 cond
= simplify_with_current_value_aux (XEXP (exp
, 1));
3845 if (cond
== true_rtx
)
3847 else if (cond
== false_rtx
)
3848 return simplify_with_current_value_aux (XEXP (exp
, 0));
3850 return attr_rtx (IOR
, cond
,
3851 simplify_with_current_value_aux (XEXP (exp
, 0)));
3854 cond
= simplify_with_current_value_aux (XEXP (exp
, 1));
3855 if (cond
== true_rtx
)
3856 return simplify_with_current_value_aux (XEXP (exp
, 0));
3857 else if (cond
== false_rtx
)
3860 return attr_rtx (AND
, cond
,
3861 simplify_with_current_value_aux (XEXP (exp
, 0)));
3864 cond
= simplify_with_current_value_aux (XEXP (exp
, 0));
3865 if (cond
== true_rtx
)
3867 else if (cond
== false_rtx
)
3870 return attr_rtx (NOT
, cond
);
3873 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3875 cond
= simplify_with_current_value_aux (XVECEXP (exp
, 0, i
));
3876 if (cond
== true_rtx
)
3877 return simplify_with_current_value_aux (XVECEXP (exp
, 0, i
+ 1));
3878 else if (cond
== false_rtx
)
3881 abort (); /* With all EQ_ATTR's of known value, a case should
3882 have been selected. */
3884 return simplify_with_current_value_aux (XEXP (exp
, 1));
3891 /* Clear the MEM_IN_STRUCT_P flag in EXP and its subexpressions. */
3894 clear_struct_flag (x
)
3899 register enum rtx_code code
;
3902 MEM_IN_STRUCT_P (x
) = 0;
3903 if (RTX_UNCHANGING_P (x
))
3906 code
= GET_CODE (x
);
3926 /* Compare the elements. If any pair of corresponding elements
3927 fail to match, return 0 for the whole things. */
3929 fmt
= GET_RTX_FORMAT (code
);
3930 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
3936 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
3937 clear_struct_flag (XVECEXP (x
, i
, j
));
3941 clear_struct_flag (XEXP (x
, i
));
3947 /* Return the number of RTX objects making up the expression X.
3948 But if we count more more than MAX objects, stop counting. */
3951 count_sub_rtxs (x
, max
)
3957 register enum rtx_code code
;
3961 code
= GET_CODE (x
);
3981 /* Compare the elements. If any pair of corresponding elements
3982 fail to match, return 0 for the whole things. */
3984 fmt
= GET_RTX_FORMAT (code
);
3985 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
3994 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
3995 total
+= count_sub_rtxs (XVECEXP (x
, i
, j
), max
);
3999 total
+= count_sub_rtxs (XEXP (x
, i
), max
);
4007 /* Create table entries for DEFINE_ATTR. */
4013 struct attr_desc
*attr
;
4014 struct attr_value
*av
;
4018 /* Make a new attribute structure. Check for duplicate by looking at
4019 attr->default_val, since it is initialized by this routine. */
4020 attr
= find_attr (XSTR (exp
, 0), 1);
4021 if (attr
->default_val
)
4022 fatal ("Duplicate definition for `%s' attribute", attr
->name
);
4024 if (*XSTR (exp
, 1) == '\0')
4025 attr
->is_numeric
= 1;
4028 name_ptr
= XSTR (exp
, 1);
4029 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
4031 av
= (struct attr_value
*) oballoc (sizeof (struct attr_value
));
4032 av
->value
= attr_rtx (CONST_STRING
, p
);
4033 av
->next
= attr
->first_value
;
4034 attr
->first_value
= av
;
4035 av
->first_insn
= NULL
;
4037 av
->has_asm_insn
= 0;
4041 if (GET_CODE (XEXP (exp
, 2)) == CONST
)
4044 if (attr
->is_numeric
)
4045 fatal ("Constant attributes may not take numeric values");
4046 /* Get rid of the CONST node. It is allowed only at top-level. */
4047 XEXP (exp
, 2) = XEXP (XEXP (exp
, 2), 0);
4050 if (! strcmp (attr
->name
, "length") && ! attr
->is_numeric
)
4051 fatal ("`length' attribute must take numeric values");
4053 /* Set up the default value. */
4054 XEXP (exp
, 2) = check_attr_value (XEXP (exp
, 2), attr
);
4055 attr
->default_val
= get_attr_value (XEXP (exp
, 2), attr
, -2);
4058 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
4059 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
4060 number of alternatives as this should be checked elsewhere. */
4063 count_alternatives (exp
)
4069 if (GET_CODE (exp
) == MATCH_OPERAND
)
4070 return n_comma_elts (XSTR (exp
, 2));
4072 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
4073 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
4078 n
= count_alternatives (XEXP (exp
, i
));
4085 if (XVEC (exp
, i
) != NULL
)
4086 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
4088 n
= count_alternatives (XVECEXP (exp
, i
, j
));
4097 /* Returns non-zero if the given expression contains an EQ_ATTR with the
4098 `alternative' attribute. */
4101 compares_alternatives_p (exp
)
4107 if (GET_CODE (exp
) == EQ_ATTR
&& XSTR (exp
, 0) == alternative_name
)
4110 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
4111 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
4116 if (compares_alternatives_p (XEXP (exp
, i
)))
4121 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
4122 if (compares_alternatives_p (XVECEXP (exp
, i
, j
)))
4130 /* Returns non-zero is INNER is contained in EXP. */
4133 contained_in_p (inner
, exp
)
4140 if (rtx_equal_p (inner
, exp
))
4143 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
4144 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
4149 if (contained_in_p (inner
, XEXP (exp
, i
)))
4154 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
4155 if (contained_in_p (inner
, XVECEXP (exp
, i
, j
)))
4163 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
4169 struct insn_def
*id
;
4171 id
= (struct insn_def
*) oballoc (sizeof (struct insn_def
));
4176 switch (GET_CODE (exp
))
4179 id
->insn_code
= insn_code_number
++;
4180 id
->insn_index
= insn_index_number
++;
4181 id
->num_alternatives
= count_alternatives (exp
);
4182 if (id
->num_alternatives
== 0)
4183 id
->num_alternatives
= 1;
4187 case DEFINE_PEEPHOLE
:
4188 id
->insn_code
= insn_code_number
++;
4189 id
->insn_index
= insn_index_number
++;
4190 id
->num_alternatives
= count_alternatives (exp
);
4191 if (id
->num_alternatives
== 0)
4192 id
->num_alternatives
= 1;
4196 case DEFINE_ASM_ATTRIBUTES
:
4198 id
->insn_index
= -1;
4199 id
->num_alternatives
= 1;
4201 got_define_asm_attributes
= 1;
4209 /* Process a DEFINE_DELAY. Validate the vector length, check if annul
4210 true or annul false is specified, and make a `struct delay_desc'. */
4216 struct delay_desc
*delay
;
4219 if (XVECLEN (def
, 1) % 3 != 0)
4220 fatal ("Number of elements in DEFINE_DELAY must be multiple of three.");
4222 for (i
= 0; i
< XVECLEN (def
, 1); i
+= 3)
4224 if (XVECEXP (def
, 1, i
+ 1))
4225 have_annul_true
= 1;
4226 if (XVECEXP (def
, 1, i
+ 2))
4227 have_annul_false
= 1;
4230 delay
= (struct delay_desc
*) oballoc (sizeof (struct delay_desc
));
4232 delay
->num
= ++num_delays
;
4233 delay
->next
= delays
;
4237 /* Process a DEFINE_FUNCTION_UNIT.
4239 This gives information about a function unit contained in the CPU.
4240 We fill in a `struct function_unit_op' and a `struct function_unit'
4241 with information used later by `expand_unit'. */
4247 struct function_unit
*unit
;
4248 struct function_unit_op
*op
;
4249 char *name
= XSTR (def
, 0);
4250 int multiplicity
= XINT (def
, 1);
4251 int simultaneity
= XINT (def
, 2);
4252 rtx condexp
= XEXP (def
, 3);
4253 int ready_cost
= MAX (XINT (def
, 4), 1);
4254 int issue_delay
= MAX (XINT (def
, 5), 1);
4256 /* See if we have already seen this function unit. If so, check that
4257 the multiplicity and simultaneity values are the same. If not, make
4258 a structure for this function unit. */
4259 for (unit
= units
; unit
; unit
= unit
->next
)
4260 if (! strcmp (unit
->name
, name
))
4262 if (unit
->multiplicity
!= multiplicity
4263 || unit
->simultaneity
!= simultaneity
)
4264 fatal ("Differing specifications given for `%s' function unit.",
4271 unit
= (struct function_unit
*) oballoc (sizeof (struct function_unit
));
4273 unit
->multiplicity
= multiplicity
;
4274 unit
->simultaneity
= simultaneity
;
4275 unit
->issue_delay
.min
= unit
->issue_delay
.max
= issue_delay
;
4276 unit
->num
= num_units
++;
4277 unit
->num_opclasses
= 0;
4278 unit
->condexp
= false_rtx
;
4284 /* Make a new operation class structure entry and initialize it. */
4285 op
= (struct function_unit_op
*) oballoc (sizeof (struct function_unit_op
));
4286 op
->condexp
= condexp
;
4287 op
->num
= unit
->num_opclasses
++;
4288 op
->ready
= ready_cost
;
4289 op
->issue_delay
= issue_delay
;
4290 op
->next
= unit
->ops
;
4293 /* Set our issue expression based on whether or not an optional conflict
4294 vector was specified. */
4297 /* Compute the IOR of all the specified expressions. */
4298 rtx orexp
= false_rtx
;
4301 for (i
= 0; i
< XVECLEN (def
, 6); i
++)
4302 orexp
= insert_right_side (IOR
, orexp
, XVECEXP (def
, 6, i
), -2, -2);
4304 op
->conflict_exp
= orexp
;
4305 extend_range (&unit
->issue_delay
, 1, issue_delay
);
4309 op
->conflict_exp
= true_rtx
;
4310 extend_range (&unit
->issue_delay
, issue_delay
, issue_delay
);
4313 /* Merge our conditional into that of the function unit so we can determine
4314 which insns are used by the function unit. */
4315 unit
->condexp
= insert_right_side (IOR
, unit
->condexp
, op
->condexp
, -2, -2);
4318 /* Given a piece of RTX, print a C expression to test its truth value.
4319 We use AND and IOR both for logical and bit-wise operations, so
4320 interpret them as logical unless they are inside a comparison expression.
4321 The second operand of this function will be non-zero in that case. */
4324 write_test_expr (exp
, in_comparison
)
4328 int comparison_operator
= 0;
4330 struct attr_desc
*attr
;
4332 /* In order not to worry about operator precedence, surround our part of
4333 the expression with parentheses. */
4336 code
= GET_CODE (exp
);
4339 /* Binary operators. */
4341 case GE
: case GT
: case GEU
: case GTU
:
4342 case LE
: case LT
: case LEU
: case LTU
:
4343 comparison_operator
= 1;
4345 case PLUS
: case MINUS
: case MULT
: case DIV
: case MOD
:
4346 case AND
: case IOR
: case XOR
:
4347 case ASHIFT
: case LSHIFTRT
: case ASHIFTRT
:
4348 write_test_expr (XEXP (exp
, 0), in_comparison
|| comparison_operator
);
4364 printf (" >= (unsigned) ");
4367 printf (" > (unsigned) ");
4376 printf (" <= (unsigned) ");
4379 printf (" < (unsigned) ");
4422 write_test_expr (XEXP (exp
, 1), in_comparison
|| comparison_operator
);
4426 /* Special-case (not (eq_attrq "alternative" "x")) */
4427 if (! in_comparison
&& GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
4428 && XSTR (XEXP (exp
, 0), 0) == alternative_name
)
4430 printf ("which_alternative != %s", XSTR (XEXP (exp
, 0), 1));
4434 /* Otherwise, fall through to normal unary operator. */
4436 /* Unary operators. */
4456 write_test_expr (XEXP (exp
, 0), in_comparison
);
4459 /* Comparison test of an attribute with a value. Most of these will
4460 have been removed by optimization. Handle "alternative"
4461 specially and give error if EQ_ATTR present inside a comparison. */
4464 fatal ("EQ_ATTR not valid inside comparison");
4466 if (XSTR (exp
, 0) == alternative_name
)
4468 printf ("which_alternative == %s", XSTR (exp
, 1));
4472 attr
= find_attr (XSTR (exp
, 0), 0);
4473 if (! attr
) abort ();
4475 /* Now is the time to expand the value of a constant attribute. */
4478 write_test_expr (evaluate_eq_attr (exp
, attr
->default_val
->value
,
4484 printf ("get_attr_%s (insn) == ", attr
->name
);
4485 write_attr_valueq (attr
, XSTR (exp
, 1));
4489 /* Comparison test of flags for define_delays. */
4492 fatal ("ATTR_FLAG not valid inside comparison");
4493 printf ("(flags & ATTR_FLAG_%s) != 0", XSTR (exp
, 0));
4496 /* See if an operand matches a predicate. */
4498 /* If only a mode is given, just ensure the mode matches the operand.
4499 If neither a mode nor predicate is given, error. */
4500 if (XSTR (exp
, 1) == NULL
|| *XSTR (exp
, 1) == '\0')
4502 if (GET_MODE (exp
) == VOIDmode
)
4503 fatal ("Null MATCH_OPERAND specified as test");
4505 printf ("GET_MODE (operands[%d]) == %smode",
4506 XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
4509 printf ("%s (operands[%d], %smode)",
4510 XSTR (exp
, 1), XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
4513 /* Constant integer. */
4515 #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
4516 printf ("%d", XWINT (exp
, 0));
4518 printf ("%ld", XWINT (exp
, 0));
4522 /* A random C expression. */
4524 printf ("%s", XSTR (exp
, 0));
4527 /* The address of the branch target. */
4529 printf ("insn_addresses[INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])]",
4530 XINT (exp
, 0), XINT (exp
, 0), XINT (exp
, 0));
4533 /* The address of the current insn. It would be more consistent with
4534 other usage to make this the address of the NEXT insn, but this gets
4535 too confusing because of the ambiguity regarding the length of the
4538 printf ("insn_current_address");
4542 fatal ("bad RTX code `%s' in attribute calculation\n",
4543 GET_RTX_NAME (code
));
4549 /* Given an attribute value, return the maximum CONST_STRING argument
4550 encountered. It is assumed that they are all numeric. */
4553 max_attr_value (exp
)
4556 int current_max
= 0;
4560 if (GET_CODE (exp
) == CONST_STRING
)
4561 return atoi (XSTR (exp
, 0));
4563 else if (GET_CODE (exp
) == COND
)
4565 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
4567 n
= max_attr_value (XVECEXP (exp
, 0, i
+ 1));
4568 if (n
> current_max
)
4572 n
= max_attr_value (XEXP (exp
, 1));
4573 if (n
> current_max
)
4577 else if (GET_CODE (exp
) == IF_THEN_ELSE
)
4579 current_max
= max_attr_value (XEXP (exp
, 1));
4580 n
= max_attr_value (XEXP (exp
, 2));
4581 if (n
> current_max
)
4591 /* Scan an attribute value, possibly a conditional, and record what actions
4592 will be required to do any conditional tests in it.
4595 `must_extract' if we need to extract the insn operands
4596 `must_constrain' if we must compute `which_alternative'
4597 `address_used' if an address expression was used
4598 `length_used' if an (eq_attr "length" ...) was used
4602 walk_attr_value (exp
)
4612 code
= GET_CODE (exp
);
4616 if (! RTX_UNCHANGING_P (exp
))
4617 /* Since this is an arbitrary expression, it can look at anything.
4618 However, constant expressions do not depend on any particular
4620 must_extract
= must_constrain
= 1;
4628 if (XSTR (exp
, 0) == alternative_name
)
4629 must_extract
= must_constrain
= 1;
4630 else if (strcmp (XSTR (exp
, 0), "length") == 0)
4650 for (i
= 0, fmt
= GET_RTX_FORMAT (code
); i
< GET_RTX_LENGTH (code
); i
++)
4655 walk_attr_value (XEXP (exp
, i
));
4659 if (XVEC (exp
, i
) != NULL
)
4660 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
4661 walk_attr_value (XVECEXP (exp
, i
, j
));
4666 /* Write out a function to obtain the attribute for a given INSN. */
4669 write_attr_get (attr
)
4670 struct attr_desc
*attr
;
4672 struct attr_value
*av
, *common_av
;
4674 /* Find the most used attribute value. Handle that as the `default' of the
4675 switch we will generate. */
4676 common_av
= find_most_used (attr
);
4678 /* Write out start of function, then all values with explicit `case' lines,
4679 then a `default', then the value with the most uses. */
4680 if (!attr
->is_numeric
)
4681 printf ("enum attr_%s\n", attr
->name
);
4682 else if (attr
->unsigned_p
)
4683 printf ("unsigned int\n");
4687 /* If the attribute name starts with a star, the remainder is the name of
4688 the subroutine to use, instead of `get_attr_...'. */
4689 if (attr
->name
[0] == '*')
4690 printf ("%s (insn)\n", &attr
->name
[1]);
4691 else if (attr
->is_const
== 0)
4692 printf ("get_attr_%s (insn)\n", attr
->name
);
4695 printf ("get_attr_%s ()\n", attr
->name
);
4698 for (av
= attr
->first_value
; av
; av
= av
->next
)
4699 if (av
->num_insns
!= 0)
4700 write_attr_set (attr
, 2, av
->value
, "return", ";",
4701 true_rtx
, av
->first_insn
->insn_code
,
4702 av
->first_insn
->insn_index
);
4707 printf (" rtx insn;\n");
4709 printf (" switch (recog_memoized (insn))\n");
4712 for (av
= attr
->first_value
; av
; av
= av
->next
)
4713 if (av
!= common_av
)
4714 write_attr_case (attr
, av
, 1, "return", ";", 4, true_rtx
);
4716 write_attr_case (attr
, common_av
, 0, "return", ";", 4, true_rtx
);
4717 printf (" }\n}\n\n");
4720 /* Given an AND tree of known true terms (because we are inside an `if' with
4721 that as the condition or are in an `else' clause) and an expression,
4722 replace any known true terms with TRUE. Use `simplify_and_tree' to do
4723 the bulk of the work. */
4726 eliminate_known_true (known_true
, exp
, insn_code
, insn_index
)
4729 int insn_code
, insn_index
;
4733 known_true
= SIMPLIFY_TEST_EXP (known_true
, insn_code
, insn_index
);
4735 if (GET_CODE (known_true
) == AND
)
4737 exp
= eliminate_known_true (XEXP (known_true
, 0), exp
,
4738 insn_code
, insn_index
);
4739 exp
= eliminate_known_true (XEXP (known_true
, 1), exp
,
4740 insn_code
, insn_index
);
4745 exp
= simplify_and_tree (exp
, &term
, insn_code
, insn_index
);
4751 /* Write out a series of tests and assignment statements to perform tests and
4752 sets of an attribute value. We are passed an indentation amount and prefix
4753 and suffix strings to write around each attribute value (e.g., "return"
4757 write_attr_set (attr
, indent
, value
, prefix
, suffix
, known_true
,
4758 insn_code
, insn_index
)
4759 struct attr_desc
*attr
;
4765 int insn_code
, insn_index
;
4767 if (GET_CODE (value
) == CONST_STRING
)
4769 write_indent (indent
);
4770 printf ("%s ", prefix
);
4771 write_attr_value (attr
, value
);
4772 printf ("%s\n", suffix
);
4774 else if (GET_CODE (value
) == COND
)
4776 /* Assume the default value will be the default of the COND unless we
4777 find an always true expression. */
4778 rtx default_val
= XEXP (value
, 1);
4779 rtx our_known_true
= known_true
;
4784 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
4789 testexp
= eliminate_known_true (our_known_true
,
4790 XVECEXP (value
, 0, i
),
4791 insn_code
, insn_index
);
4792 newexp
= attr_rtx (NOT
, testexp
);
4793 newexp
= insert_right_side (AND
, our_known_true
, newexp
,
4794 insn_code
, insn_index
);
4796 /* If the test expression is always true or if the next `known_true'
4797 expression is always false, this is the last case, so break
4798 out and let this value be the `else' case. */
4799 if (testexp
== true_rtx
|| newexp
== false_rtx
)
4801 default_val
= XVECEXP (value
, 0, i
+ 1);
4805 /* Compute the expression to pass to our recursive call as being
4807 inner_true
= insert_right_side (AND
, our_known_true
,
4808 testexp
, insn_code
, insn_index
);
4810 /* If this is always false, skip it. */
4811 if (inner_true
== false_rtx
)
4814 write_indent (indent
);
4815 printf ("%sif ", first_if
? "" : "else ");
4817 write_test_expr (testexp
, 0);
4819 write_indent (indent
+ 2);
4822 write_attr_set (attr
, indent
+ 4,
4823 XVECEXP (value
, 0, i
+ 1), prefix
, suffix
,
4824 inner_true
, insn_code
, insn_index
);
4825 write_indent (indent
+ 2);
4827 our_known_true
= newexp
;
4832 write_indent (indent
);
4834 write_indent (indent
+ 2);
4838 write_attr_set (attr
, first_if
? indent
: indent
+ 4, default_val
,
4839 prefix
, suffix
, our_known_true
, insn_code
, insn_index
);
4843 write_indent (indent
+ 2);
4851 /* Write out the computation for one attribute value. */
4854 write_attr_case (attr
, av
, write_case_lines
, prefix
, suffix
, indent
,
4856 struct attr_desc
*attr
;
4857 struct attr_value
*av
;
4858 int write_case_lines
;
4859 char *prefix
, *suffix
;
4863 struct insn_ent
*ie
;
4865 if (av
->num_insns
== 0)
4868 if (av
->has_asm_insn
)
4870 write_indent (indent
);
4871 printf ("case -1:\n");
4872 write_indent (indent
+ 2);
4873 printf ("if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
4874 write_indent (indent
+ 2);
4875 printf (" && asm_noperands (PATTERN (insn)) < 0)\n");
4876 write_indent (indent
+ 2);
4877 printf (" fatal_insn_not_found (insn);\n");
4880 if (write_case_lines
)
4882 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
4883 if (ie
->insn_code
!= -1)
4885 write_indent (indent
);
4886 printf ("case %d:\n", ie
->insn_code
);
4891 write_indent (indent
);
4892 printf ("default:\n");
4895 /* See what we have to do to output this value. */
4896 must_extract
= must_constrain
= address_used
= 0;
4897 walk_attr_value (av
->value
);
4901 write_indent (indent
+ 2);
4902 printf ("insn_extract (insn);\n");
4907 #ifdef REGISTER_CONSTRAINTS
4908 write_indent (indent
+ 2);
4909 printf ("if (! constrain_operands (INSN_CODE (insn), reload_completed))\n");
4910 write_indent (indent
+ 2);
4911 printf (" fatal_insn_not_found (insn);\n");
4915 write_attr_set (attr
, indent
+ 2, av
->value
, prefix
, suffix
,
4916 known_true
, av
->first_insn
->insn_code
,
4917 av
->first_insn
->insn_index
);
4919 if (strncmp (prefix
, "return", 6))
4921 write_indent (indent
+ 2);
4922 printf ("break;\n");
4927 /* Utilities to write names in various forms. */
4930 write_attr_valueq (attr
, s
)
4931 struct attr_desc
*attr
;
4934 if (attr
->is_numeric
)
4937 /* Make the blockage range values easier to read. */
4939 printf (" /* 0x%x */", atoi (s
));
4943 write_upcase (attr
->name
);
4950 write_attr_value (attr
, value
)
4951 struct attr_desc
*attr
;
4954 if (GET_CODE (value
) != CONST_STRING
)
4957 write_attr_valueq (attr
, XSTR (value
, 0));
4965 if (*str
< 'a' || *str
> 'z')
4966 printf ("%c", *str
++);
4968 printf ("%c", *str
++ - 'a' + 'A');
4972 write_indent (indent
)
4975 for (; indent
> 8; indent
-= 8)
4978 for (; indent
; indent
--)
4982 /* Write a subroutine that is given an insn that requires a delay slot, a
4983 delay slot ordinal, and a candidate insn. It returns non-zero if the
4984 candidate can be placed in the specified delay slot of the insn.
4986 We can write as many as three subroutines. `eligible_for_delay'
4987 handles normal delay slots, `eligible_for_annul_true' indicates that
4988 the specified insn can be annulled if the branch is true, and likewise
4989 for `eligible_for_annul_false'.
4991 KIND is a string distinguishing these three cases ("delay", "annul_true",
4992 or "annul_false"). */
4995 write_eligible_delay (kind
)
4998 struct delay_desc
*delay
;
5001 struct attr_desc
*attr
;
5002 struct attr_value
*av
, *common_av
;
5005 /* Compute the maximum number of delay slots required. We use the delay
5006 ordinal times this number plus one, plus the slot number as an index into
5007 the appropriate predicate to test. */
5009 for (delay
= delays
, max_slots
= 0; delay
; delay
= delay
->next
)
5010 if (XVECLEN (delay
->def
, 1) / 3 > max_slots
)
5011 max_slots
= XVECLEN (delay
->def
, 1) / 3;
5013 /* Write function prelude. */
5016 printf ("eligible_for_%s (delay_insn, slot, candidate_insn, flags)\n",
5018 printf (" rtx delay_insn;\n");
5019 printf (" int slot;\n");
5020 printf (" rtx candidate_insn;\n");
5021 printf (" int flags;\n");
5023 printf (" rtx insn;\n");
5025 printf (" if (slot >= %d)\n", max_slots
);
5026 printf (" abort ();\n");
5029 /* If more than one delay type, find out which type the delay insn is. */
5033 attr
= find_attr ("*delay_type", 0);
5034 if (! attr
) abort ();
5035 common_av
= find_most_used (attr
);
5037 printf (" insn = delay_insn;\n");
5038 printf (" switch (recog_memoized (insn))\n");
5041 sprintf (str
, " * %d;\n break;", max_slots
);
5042 for (av
= attr
->first_value
; av
; av
= av
->next
)
5043 if (av
!= common_av
)
5044 write_attr_case (attr
, av
, 1, "slot +=", str
, 4, true_rtx
);
5046 write_attr_case (attr
, common_av
, 0, "slot +=", str
, 4, true_rtx
);
5049 /* Ensure matched. Otherwise, shouldn't have been called. */
5050 printf (" if (slot < %d)\n", max_slots
);
5051 printf (" abort ();\n\n");
5054 /* If just one type of delay slot, write simple switch. */
5055 if (num_delays
== 1 && max_slots
== 1)
5057 printf (" insn = candidate_insn;\n");
5058 printf (" switch (recog_memoized (insn))\n");
5061 attr
= find_attr ("*delay_1_0", 0);
5062 if (! attr
) abort ();
5063 common_av
= find_most_used (attr
);
5065 for (av
= attr
->first_value
; av
; av
= av
->next
)
5066 if (av
!= common_av
)
5067 write_attr_case (attr
, av
, 1, "return", ";", 4, true_rtx
);
5069 write_attr_case (attr
, common_av
, 0, "return", ";", 4, true_rtx
);
5075 /* Write a nested CASE. The first indicates which condition we need to
5076 test, and the inner CASE tests the condition. */
5077 printf (" insn = candidate_insn;\n");
5078 printf (" switch (slot)\n");
5081 for (delay
= delays
; delay
; delay
= delay
->next
)
5082 for (i
= 0; i
< XVECLEN (delay
->def
, 1); i
+= 3)
5084 printf (" case %d:\n",
5085 (i
/ 3) + (num_delays
== 1 ? 0 : delay
->num
* max_slots
));
5086 printf (" switch (recog_memoized (insn))\n");
5089 sprintf (str
, "*%s_%d_%d", kind
, delay
->num
, i
/ 3);
5090 attr
= find_attr (str
, 0);
5091 if (! attr
) abort ();
5092 common_av
= find_most_used (attr
);
5094 for (av
= attr
->first_value
; av
; av
= av
->next
)
5095 if (av
!= common_av
)
5096 write_attr_case (attr
, av
, 1, "return", ";", 8, true_rtx
);
5098 write_attr_case (attr
, common_av
, 0, "return", ";", 8, true_rtx
);
5102 printf (" default:\n");
5103 printf (" abort ();\n");
5110 /* Write routines to compute conflict cost for function units. Then write a
5111 table describing the available function units. */
5114 write_function_unit_info ()
5116 struct function_unit
*unit
;
5119 /* Write out conflict routines for function units. Don't bother writing
5120 one if there is only one issue delay value. */
5122 for (unit
= units
; unit
; unit
= unit
->next
)
5124 if (unit
->needs_blockage_function
)
5125 write_complex_function (unit
, "blockage", "block");
5127 /* If the minimum and maximum conflict costs are the same, there
5128 is only one value, so we don't need a function. */
5129 if (! unit
->needs_conflict_function
)
5131 unit
->default_cost
= make_numeric_value (unit
->issue_delay
.max
);
5135 /* The function first computes the case from the candidate insn. */
5136 unit
->default_cost
= make_numeric_value (0);
5137 write_complex_function (unit
, "conflict_cost", "cost");
5140 /* Now that all functions have been written, write the table describing
5141 the function units. The name is included for documentation purposes
5144 printf ("struct function_unit_desc function_units[] = {\n");
5146 /* Write out the descriptions in numeric order, but don't force that order
5147 on the list. Doing so increases the runtime of genattrtab.c. */
5148 for (i
= 0; i
< num_units
; i
++)
5150 for (unit
= units
; unit
; unit
= unit
->next
)
5154 printf (" {\"%s\", %d, %d, %d, %s, %d, %s_unit_ready_cost, ",
5155 unit
->name
, 1 << unit
->num
, unit
->multiplicity
,
5156 unit
->simultaneity
, XSTR (unit
->default_cost
, 0),
5157 unit
->issue_delay
.max
, unit
->name
);
5159 if (unit
->needs_conflict_function
)
5160 printf ("%s_unit_conflict_cost, ", unit
->name
);
5164 printf ("%d, ", unit
->max_blockage
);
5166 if (unit
->needs_range_function
)
5167 printf ("%s_unit_blockage_range, ", unit
->name
);
5171 if (unit
->needs_blockage_function
)
5172 printf ("%s_unit_blockage", unit
->name
);
5183 write_complex_function (unit
, name
, connection
)
5184 struct function_unit
*unit
;
5185 char *name
, *connection
;
5187 struct attr_desc
*case_attr
, *attr
;
5188 struct attr_value
*av
, *common_av
;
5194 printf ("static int\n");
5195 printf ("%s_unit_%s (executing_insn, candidate_insn)\n",
5197 printf (" rtx executing_insn;\n");
5198 printf (" rtx candidate_insn;\n");
5200 printf (" rtx insn;\n");
5201 printf (" int casenum;\n\n");
5202 printf (" insn = executing_insn;\n");
5203 printf (" switch (recog_memoized (insn))\n");
5206 /* Write the `switch' statement to get the case value. */
5207 str
= (char *) alloca (strlen (unit
->name
) + strlen (name
) + strlen (connection
) + 10);
5208 sprintf (str
, "*%s_cases", unit
->name
);
5209 case_attr
= find_attr (str
, 0);
5210 if (! case_attr
) abort ();
5211 common_av
= find_most_used (case_attr
);
5213 for (av
= case_attr
->first_value
; av
; av
= av
->next
)
5214 if (av
!= common_av
)
5215 write_attr_case (case_attr
, av
, 1,
5216 "casenum =", ";", 4, unit
->condexp
);
5218 write_attr_case (case_attr
, common_av
, 0,
5219 "casenum =", ";", 4, unit
->condexp
);
5222 /* Now write an outer switch statement on each case. Then write
5223 the tests on the executing function within each. */
5224 printf (" insn = candidate_insn;\n");
5225 printf (" switch (casenum)\n");
5228 for (i
= 0; i
< unit
->num_opclasses
; i
++)
5230 /* Ensure using this case. */
5232 for (av
= case_attr
->first_value
; av
; av
= av
->next
)
5234 && contained_in_p (make_numeric_value (i
), av
->value
))
5240 printf (" case %d:\n", i
);
5241 sprintf (str
, "*%s_%s_%d", unit
->name
, connection
, i
);
5242 attr
= find_attr (str
, 0);
5243 if (! attr
) abort ();
5245 /* If single value, just write it. */
5246 value
= find_single_value (attr
);
5248 write_attr_set (attr
, 6, value
, "return", ";\n", true_rtx
, -2, -2);
5251 common_av
= find_most_used (attr
);
5252 printf (" switch (recog_memoized (insn))\n");
5255 for (av
= attr
->first_value
; av
; av
= av
->next
)
5256 if (av
!= common_av
)
5257 write_attr_case (attr
, av
, 1,
5258 "return", ";", 8, unit
->condexp
);
5260 write_attr_case (attr
, common_av
, 0,
5261 "return", ";", 8, unit
->condexp
);
5266 printf (" }\n}\n\n");
5269 /* This page contains miscellaneous utility routines. */
5271 /* Given a string, return the number of comma-separated elements in it.
5272 Return 0 for the null string. */
5283 for (n
= 1; *s
; s
++)
5290 /* Given a pointer to a (char *), return a malloc'ed string containing the
5291 next comma-separated element. Advance the pointer to after the string
5292 scanned, or the end-of-string. Return NULL if at end of string. */
5295 next_comma_elt (pstr
)
5304 /* Find end of string to compute length. */
5305 for (p
= *pstr
; *p
!= ',' && *p
!= '\0'; p
++)
5308 out_str
= attr_string (*pstr
, p
- *pstr
);
5317 /* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
5318 is non-zero, build a new attribute, if one does not exist. */
5320 static struct attr_desc
*
5321 find_attr (name
, create
)
5325 struct attr_desc
*attr
;
5328 /* Before we resort to using `strcmp', see if the string address matches
5329 anywhere. In most cases, it should have been canonicalized to do so. */
5330 if (name
== alternative_name
)
5333 index
= name
[0] & (MAX_ATTRS_INDEX
- 1);
5334 for (attr
= attrs
[index
]; attr
; attr
= attr
->next
)
5335 if (name
== attr
->name
)
5338 /* Otherwise, do it the slow way. */
5339 for (attr
= attrs
[index
]; attr
; attr
= attr
->next
)
5340 if (name
[0] == attr
->name
[0] && ! strcmp (name
, attr
->name
))
5346 attr
= (struct attr_desc
*) oballoc (sizeof (struct attr_desc
));
5347 attr
->name
= attr_string (name
, strlen (name
));
5348 attr
->first_value
= attr
->default_val
= NULL
;
5349 attr
->is_numeric
= attr
->negative_ok
= attr
->is_const
= attr
->is_special
= 0;
5350 attr
->next
= attrs
[index
];
5351 attrs
[index
] = attr
;
5356 /* Create internal attribute with the given default value. */
5359 make_internal_attr (name
, value
, special
)
5364 struct attr_desc
*attr
;
5366 attr
= find_attr (name
, 1);
5367 if (attr
->default_val
)
5370 attr
->is_numeric
= 1;
5372 attr
->is_special
= (special
& 1) != 0;
5373 attr
->negative_ok
= (special
& 2) != 0;
5374 attr
->unsigned_p
= (special
& 4) != 0;
5375 attr
->default_val
= get_attr_value (value
, attr
, -2);
5378 /* Find the most used value of an attribute. */
5380 static struct attr_value
*
5381 find_most_used (attr
)
5382 struct attr_desc
*attr
;
5384 struct attr_value
*av
;
5385 struct attr_value
*most_used
;
5391 for (av
= attr
->first_value
; av
; av
= av
->next
)
5392 if (av
->num_insns
> nuses
)
5393 nuses
= av
->num_insns
, most_used
= av
;
5398 /* If an attribute only has a single value used, return it. Otherwise
5402 find_single_value (attr
)
5403 struct attr_desc
*attr
;
5405 struct attr_value
*av
;
5408 unique_value
= NULL
;
5409 for (av
= attr
->first_value
; av
; av
= av
->next
)
5415 unique_value
= av
->value
;
5418 return unique_value
;
5421 /* Return (attr_value "n") */
5424 make_numeric_value (n
)
5427 static rtx int_values
[20];
5434 if (n
< 20 && int_values
[n
])
5435 return int_values
[n
];
5437 p
= attr_printf (MAX_DIGITS
, "%d", n
);
5438 exp
= attr_rtx (CONST_STRING
, p
);
5441 int_values
[n
] = exp
;
5447 extend_range (range
, min
, max
)
5448 struct range
*range
;
5452 if (range
->min
> min
) range
->min
= min
;
5453 if (range
->max
< max
) range
->max
= max
;
5457 xrealloc (ptr
, size
)
5461 char *result
= (char *) realloc (ptr
, size
);
5463 fatal ("virtual memory exhausted");
5471 register char *val
= (char *) malloc (size
);
5474 fatal ("virtual memory exhausted");
5479 copy_rtx_unchanging (orig
)
5484 register RTX_CODE code
;
5487 if (RTX_UNCHANGING_P (orig
) || MEM_IN_STRUCT_P (orig
))
5490 MEM_IN_STRUCT_P (orig
) = 1;
5494 code
= GET_CODE (orig
);
5507 copy
= rtx_alloc (code
);
5508 PUT_MODE (copy
, GET_MODE (orig
));
5509 RTX_UNCHANGING_P (copy
) = 1;
5511 bcopy ((char *) &XEXP (orig
, 0), (char *) &XEXP (copy
, 0),
5512 GET_RTX_LENGTH (GET_CODE (copy
)) * sizeof (rtx
));
5519 fatal
VPROTO((char *s
, ...))
5521 #ifndef ANSI_PROTOTYPES
5528 #ifndef ANSI_PROTOTYPES
5529 s
= va_arg (ap
, char *);
5532 fprintf (stderr
, "genattrtab: ");
5533 vfprintf (stderr
, s
, ap
);
5535 fprintf (stderr
, "\n");
5536 exit (FATAL_EXIT_CODE
);
5538 #else /* not HAVE_VPRINTF */
5544 fprintf (stderr
, "genattrtab: ");
5545 fprintf (stderr
, s
, a1
, a2
);
5546 fprintf (stderr
, "\n");
5547 exit (FATAL_EXIT_CODE
);
5549 #endif /* not HAVE_VPRINTF */
5551 /* More 'friendly' abort that prints the line and file.
5552 config.h can #define abort fancy_abort if you like that sort of thing. */
5557 fatal ("Internal gcc abort.");
5560 /* Determine if an insn has a constant number of delay slots, i.e., the
5561 number of delay slots is not a function of the length of the insn. */
5564 write_const_num_delay_slots ()
5566 struct attr_desc
*attr
= find_attr ("*num_delay_slots", 0);
5567 struct attr_value
*av
;
5568 struct insn_ent
*ie
;
5573 printf ("int\nconst_num_delay_slots (insn)\n");
5574 printf (" rtx insn;\n");
5576 printf (" switch (recog_memoized (insn))\n");
5579 for (av
= attr
->first_value
; av
; av
= av
->next
)
5582 walk_attr_value (av
->value
);
5585 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
5586 if (ie
->insn_code
!= -1)
5587 printf (" case %d:\n", ie
->insn_code
);
5588 printf (" return 0;\n");
5592 printf (" default:\n");
5593 printf (" return 1;\n");
5607 struct attr_desc
*attr
;
5608 struct insn_def
*id
;
5612 #if defined (RLIMIT_STACK) && defined (HAVE_GETRLIMIT) && defined (HAVE_SETRLIMIT)
5613 /* Get rid of any avoidable limit on stack size. */
5617 /* Set the stack limit huge so that alloca does not fail. */
5618 getrlimit (RLIMIT_STACK
, &rlim
);
5619 rlim
.rlim_cur
= rlim
.rlim_max
;
5620 setrlimit (RLIMIT_STACK
, &rlim
);
5624 obstack_init (rtl_obstack
);
5625 obstack_init (hash_obstack
);
5626 obstack_init (temp_obstack
);
5629 fatal ("No input file name.");
5631 infile
= fopen (argv
[1], "r");
5635 exit (FATAL_EXIT_CODE
);
5640 /* We don't use this, but it is referenced in rtlanal.c.
5641 Set it up correctly just in case someone tries to use it someday. */
5642 pc_rtx
= rtx_alloc (PC
);
5643 PUT_MODE (pc_rtx
, VOIDmode
);
5645 /* Set up true and false rtx's */
5646 true_rtx
= rtx_alloc (CONST_INT
);
5647 XWINT (true_rtx
, 0) = 1;
5648 false_rtx
= rtx_alloc (CONST_INT
);
5649 XWINT (false_rtx
, 0) = 0;
5650 RTX_UNCHANGING_P (true_rtx
) = RTX_UNCHANGING_P (false_rtx
) = 1;
5651 RTX_INTEGRATED_P (true_rtx
) = RTX_INTEGRATED_P (false_rtx
) = 1;
5653 alternative_name
= attr_string ("alternative", strlen ("alternative"));
5655 printf ("/* Generated automatically by the program `genattrtab'\n\
5656 from the machine description file `md'. */\n\n");
5658 /* Read the machine description. */
5662 c
= read_skip_spaces (infile
);
5667 desc
= read_rtx (infile
);
5668 if (GET_CODE (desc
) == DEFINE_INSN
5669 || GET_CODE (desc
) == DEFINE_PEEPHOLE
5670 || GET_CODE (desc
) == DEFINE_ASM_ATTRIBUTES
)
5673 else if (GET_CODE (desc
) == DEFINE_EXPAND
)
5674 insn_code_number
++, insn_index_number
++;
5676 else if (GET_CODE (desc
) == DEFINE_SPLIT
)
5677 insn_code_number
++, insn_index_number
++;
5679 else if (GET_CODE (desc
) == DEFINE_ATTR
)
5682 insn_index_number
++;
5685 else if (GET_CODE (desc
) == DEFINE_DELAY
)
5688 insn_index_number
++;
5691 else if (GET_CODE (desc
) == DEFINE_FUNCTION_UNIT
)
5694 insn_index_number
++;
5698 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
5699 if (! got_define_asm_attributes
)
5701 tem
= rtx_alloc (DEFINE_ASM_ATTRIBUTES
);
5702 XVEC (tem
, 0) = rtvec_alloc (0);
5706 /* Expand DEFINE_DELAY information into new attribute. */
5710 /* Expand DEFINE_FUNCTION_UNIT information into new attributes. */
5714 printf ("#include \"config.h\"\n");
5715 printf ("#include \"system.h\"\n");
5716 printf ("#include \"rtl.h\"\n");
5717 printf ("#include \"insn-config.h\"\n");
5718 printf ("#include \"recog.h\"\n");
5719 printf ("#include \"regs.h\"\n");
5720 printf ("#include \"real.h\"\n");
5721 printf ("#include \"output.h\"\n");
5722 printf ("#include \"insn-attr.h\"\n");
5724 printf ("#define operands recog_operand\n\n");
5726 /* Make `insn_alternatives'. */
5727 insn_alternatives
= (int *) oballoc (insn_code_number
* sizeof (int));
5728 for (id
= defs
; id
; id
= id
->next
)
5729 if (id
->insn_code
>= 0)
5730 insn_alternatives
[id
->insn_code
] = (1 << id
->num_alternatives
) - 1;
5732 /* Make `insn_n_alternatives'. */
5733 insn_n_alternatives
= (int *) oballoc (insn_code_number
* sizeof (int));
5734 for (id
= defs
; id
; id
= id
->next
)
5735 if (id
->insn_code
>= 0)
5736 insn_n_alternatives
[id
->insn_code
] = id
->num_alternatives
;
5738 /* Prepare to write out attribute subroutines by checking everything stored
5739 away and building the attribute cases. */
5742 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
5743 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
5745 attr
->default_val
->value
5746 = check_attr_value (attr
->default_val
->value
, attr
);
5750 /* Construct extra attributes for `length'. */
5751 make_length_attrs ();
5753 /* Perform any possible optimizations to speed up compilation. */
5756 /* Now write out all the `gen_attr_...' routines. Do these before the
5757 special routines (specifically before write_function_unit_info), so
5758 that they get defined before they are used. */
5760 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
5761 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
5763 if (! attr
->is_special
)
5764 write_attr_get (attr
);
5767 /* Write out delay eligibility information, if DEFINE_DELAY present.
5768 (The function to compute the number of delay slots will be written
5772 write_eligible_delay ("delay");
5773 if (have_annul_true
)
5774 write_eligible_delay ("annul_true");
5775 if (have_annul_false
)
5776 write_eligible_delay ("annul_false");
5779 /* Write out information about function units. */
5781 write_function_unit_info ();
5783 /* Write out constant delay slot info */
5784 write_const_num_delay_slots ();
5787 exit (ferror (stdout
) != 0 ? FATAL_EXIT_CODE
: SUCCESS_EXIT_CODE
);