1 /* Generate code from machine description to compute values of attributes.
2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000 Free Software Foundation, Inc.
4 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
23 /* This program handles insn attributes and the DEFINE_DELAY and
24 DEFINE_FUNCTION_UNIT definitions.
26 It produces a series of functions named `get_attr_...', one for each insn
27 attribute. Each of these is given the rtx for an insn and returns a member
28 of the enum for the attribute.
30 These subroutines have the form of a `switch' on the INSN_CODE (via
31 `recog_memoized'). Each case either returns a constant attribute value
32 or a value that depends on tests on other attributes, the form of
33 operands, or some random C expression (encoded with a SYMBOL_REF
36 If the attribute `alternative', or a random C expression is present,
37 `constrain_operands' is called. If either of these cases of a reference to
38 an operand is found, `extract_insn' is called.
40 The special attribute `length' is also recognized. For this operand,
41 expressions involving the address of an operand or the current insn,
42 (address (pc)), are valid. In this case, an initial pass is made to
43 set all lengths that do not depend on address. Those that do are set to
44 the maximum length. Then each insn that depends on an address is checked
45 and possibly has its length changed. The process repeats until no further
46 changed are made. The resulting lengths are saved for use by
49 A special form of DEFINE_ATTR, where the expression for default value is a
50 CONST expression, indicates an attribute that is constant for a given run
51 of the compiler. The subroutine generated for these attributes has no
52 parameters as it does not depend on any particular insn. Constant
53 attributes are typically used to specify which variety of processor is
56 Internal attributes are defined to handle DEFINE_DELAY and
57 DEFINE_FUNCTION_UNIT. Special routines are output for these cases.
59 This program works by keeping a list of possible values for each attribute.
60 These include the basic attribute choices, default values for attribute, and
61 all derived quantities.
63 As the description file is read, the definition for each insn is saved in a
64 `struct insn_def'. When the file reading is complete, a `struct insn_ent'
65 is created for each insn and chained to the corresponding attribute value,
66 either that specified, or the default.
68 An optimization phase is then run. This simplifies expressions for each
69 insn. EQ_ATTR tests are resolved, whenever possible, to a test that
70 indicates when the attribute has the specified value for the insn. This
71 avoids recursive calls during compilation.
73 The strategy used when processing DEFINE_DELAY and DEFINE_FUNCTION_UNIT
74 definitions is to create arbitrarily complex expressions and have the
75 optimization simplify them.
77 Once optimization is complete, any required routines and definitions
80 An optimization that is not yet implemented is to hoist the constant
81 expressions entirely out of the routines and definitions that are written.
82 A way to do this is to iterate over all possible combinations of values
83 for constant attributes and generate a set of functions for that given
84 combination. An initialization function would be written that evaluates
85 the attributes and installs the corresponding set of routines and
86 definitions (each would be accessed through a pointer).
88 We use the flags in an RTX as follows:
89 `unchanging' (RTX_UNCHANGING_P): This rtx is fully simplified
90 independent of the insn code.
91 `in_struct' (MEM_IN_STRUCT_P): This rtx is fully simplified
92 for the insn code currently being processed (see optimize_attrs).
93 `integrated' (RTX_INTEGRATED_P): This rtx is permanent and unique
95 `volatil' (MEM_VOLATILE_P): During simplify_by_exploding the value of an
96 EQ_ATTR rtx is true if !volatil and false if volatil. */
102 #include "gensupport.h"
104 #ifdef HAVE_SYS_RESOURCE_H
105 # include <sys/resource.h>
108 /* We must include obstack.h after <sys/time.h>, to avoid lossage with
109 /usr/include/sys/stdtypes.h on Sun OS 4.x. */
113 static struct obstack obstack1
, obstack2
;
114 struct obstack
*hash_obstack
= &obstack1
;
115 struct obstack
*temp_obstack
= &obstack2
;
117 #define obstack_chunk_alloc xmalloc
118 #define obstack_chunk_free free
120 /* enough space to reserve for printing out ints */
121 #define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3)
123 /* Define structures used to record attributes and values. */
125 /* As each DEFINE_INSN, DEFINE_PEEPHOLE, or DEFINE_ASM_ATTRIBUTES is
126 encountered, we store all the relevant information into a
127 `struct insn_def'. This is done to allow attribute definitions to occur
128 anywhere in the file. */
132 struct insn_def
*next
; /* Next insn in chain. */
133 rtx def
; /* The DEFINE_... */
134 int insn_code
; /* Instruction number. */
135 int insn_index
; /* Expression numer in file, for errors. */
136 int lineno
; /* Line number. */
137 int num_alternatives
; /* Number of alternatives. */
138 int vec_idx
; /* Index of attribute vector in `def'. */
141 /* Once everything has been read in, we store in each attribute value a list
142 of insn codes that have that value. Here is the structure used for the
147 struct insn_ent
*next
; /* Next in chain. */
148 int insn_code
; /* Instruction number. */
149 int insn_index
; /* Index of definition in file */
150 int lineno
; /* Line number. */
153 /* Each value of an attribute (either constant or computed) is assigned a
154 structure which is used as the listhead of the insns that have that
159 rtx value
; /* Value of attribute. */
160 struct attr_value
*next
; /* Next attribute value in chain. */
161 struct insn_ent
*first_insn
; /* First insn with this value. */
162 int num_insns
; /* Number of insns with this value. */
163 int has_asm_insn
; /* True if this value used for `asm' insns */
166 /* Structure for each attribute. */
170 char *name
; /* Name of attribute. */
171 struct attr_desc
*next
; /* Next attribute. */
172 unsigned is_numeric
: 1; /* Values of this attribute are numeric. */
173 unsigned negative_ok
: 1; /* Allow negative numeric values. */
174 unsigned unsigned_p
: 1; /* Make the output function unsigned int. */
175 unsigned is_const
: 1; /* Attribute value constant for each run. */
176 unsigned is_special
: 1; /* Don't call `write_attr_set'. */
177 unsigned func_units_p
: 1; /* this is the function_units attribute */
178 unsigned blockage_p
: 1; /* this is the blockage range function */
179 struct attr_value
*first_value
; /* First value of this attribute. */
180 struct attr_value
*default_val
; /* Default value for this attribute. */
181 int lineno
; /* Line number. */
184 #define NULL_ATTR (struct attr_desc *) NULL
186 /* A range of values. */
194 /* Structure for each DEFINE_DELAY. */
198 rtx def
; /* DEFINE_DELAY expression. */
199 struct delay_desc
*next
; /* Next DEFINE_DELAY. */
200 int num
; /* Number of DEFINE_DELAY, starting at 1. */
201 int lineno
; /* Line number. */
204 /* Record information about each DEFINE_FUNCTION_UNIT. */
206 struct function_unit_op
208 rtx condexp
; /* Expression TRUE for applicable insn. */
209 struct function_unit_op
*next
; /* Next operation for this function unit. */
210 int num
; /* Ordinal for this operation type in unit. */
211 int ready
; /* Cost until data is ready. */
212 int issue_delay
; /* Cost until unit can accept another insn. */
213 rtx conflict_exp
; /* Expression TRUE for insns incurring issue delay. */
214 rtx issue_exp
; /* Expression computing issue delay. */
215 int lineno
; /* Line number. */
218 /* Record information about each function unit mentioned in a
219 DEFINE_FUNCTION_UNIT. */
223 const char *name
; /* Function unit name. */
224 struct function_unit
*next
; /* Next function unit. */
225 int num
; /* Ordinal of this unit type. */
226 int multiplicity
; /* Number of units of this type. */
227 int simultaneity
; /* Maximum number of simultaneous insns
228 on this function unit or 0 if unlimited. */
229 rtx condexp
; /* Expression TRUE for insn needing unit. */
230 int num_opclasses
; /* Number of different operation types. */
231 struct function_unit_op
*ops
; /* Pointer to first operation type. */
232 int needs_conflict_function
; /* Nonzero if a conflict function required. */
233 int needs_blockage_function
; /* Nonzero if a blockage function required. */
234 int needs_range_function
; /* Nonzero if blockage range function needed.*/
235 rtx default_cost
; /* Conflict cost, if constant. */
236 struct range issue_delay
; /* Range of issue delay values. */
237 int max_blockage
; /* Maximum time an insn blocks the unit. */
238 int first_lineno
; /* First seen line number. */
241 /* Listheads of above structures. */
243 /* This one is indexed by the first character of the attribute name. */
244 #define MAX_ATTRS_INDEX 256
245 static struct attr_desc
*attrs
[MAX_ATTRS_INDEX
];
246 static struct insn_def
*defs
;
247 static struct delay_desc
*delays
;
248 static struct function_unit
*units
;
250 /* An expression where all the unknown terms are EQ_ATTR tests can be
251 rearranged into a COND provided we can enumerate all possible
252 combinations of the unknown values. The set of combinations become the
253 tests of the COND; the value of the expression given that combination is
254 computed and becomes the corresponding value. To do this, we must be
255 able to enumerate all values for each attribute used in the expression
256 (currently, we give up if we find a numeric attribute).
258 If the set of EQ_ATTR tests used in an expression tests the value of N
259 different attributes, the list of all possible combinations can be made
260 by walking the N-dimensional attribute space defined by those
261 attributes. We record each of these as a struct dimension.
263 The algorithm relies on sharing EQ_ATTR nodes: if two nodes in an
264 expression are the same, the will also have the same address. We find
265 all the EQ_ATTR nodes by marking them MEM_VOLATILE_P. This bit later
266 represents the value of an EQ_ATTR node, so once all nodes are marked,
267 they are also given an initial value of FALSE.
269 We then separate the set of EQ_ATTR nodes into dimensions for each
270 attribute and put them on the VALUES list. Terms are added as needed by
271 `add_values_to_cover' so that all possible values of the attribute are
274 Each dimension also has a current value. This is the node that is
275 currently considered to be TRUE. If this is one of the nodes added by
276 `add_values_to_cover', all the EQ_ATTR tests in the original expression
277 will be FALSE. Otherwise, only the CURRENT_VALUE will be true.
279 NUM_VALUES is simply the length of the VALUES list and is there for
282 Once the dimensions are created, the algorithm enumerates all possible
283 values and computes the current value of the given expression. */
287 struct attr_desc
*attr
; /* Attribute for this dimension. */
288 rtx values
; /* List of attribute values used. */
289 rtx current_value
; /* Position in the list for the TRUE value. */
290 int num_values
; /* Length of the values list. */
293 /* Other variables. */
295 static int insn_code_number
;
296 static int insn_index_number
;
297 static int got_define_asm_attributes
;
298 static int must_extract
;
299 static int must_constrain
;
300 static int address_used
;
301 static int length_used
;
302 static int num_delays
;
303 static int have_annul_true
, have_annul_false
;
304 static int num_units
, num_unit_opclasses
;
305 static int num_insn_ents
;
307 /* Used as operand to `operate_exp': */
309 enum operator {PLUS_OP
, MINUS_OP
, POS_MINUS_OP
, EQ_OP
, OR_OP
, ORX_OP
, MAX_OP
, MIN_OP
, RANGE_OP
};
311 /* Stores, for each insn code, the number of constraint alternatives. */
313 static int *insn_n_alternatives
;
315 /* Stores, for each insn code, a bitmap that has bits on for each possible
318 static int *insn_alternatives
;
320 /* If nonzero, assume that the `alternative' attr has this value.
321 This is the hashed, unique string for the numeral
322 whose value is chosen alternative. */
324 static const char *current_alternative_string
;
326 /* Used to simplify expressions. */
328 static rtx true_rtx
, false_rtx
;
330 /* Used to reduce calls to `strcmp' */
332 static char *alternative_name
;
334 /* Indicate that REG_DEAD notes are valid if dead_or_set_p is ever
337 int reload_completed
= 0;
339 /* Some machines test `optimize' in macros called from rtlanal.c, so we need
340 to define it here. */
344 /* Simplify an expression. Only call the routine if there is something to
346 #define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX) \
347 (RTX_UNCHANGING_P (EXP) || MEM_IN_STRUCT_P (EXP) ? (EXP) \
348 : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
350 /* Simplify (eq_attr ("alternative") ...)
351 when we are working with a particular alternative. */
352 #define SIMPLIFY_ALTERNATIVE(EXP) \
353 if (current_alternative_string \
354 && GET_CODE ((EXP)) == EQ_ATTR \
355 && XSTR ((EXP), 0) == alternative_name) \
356 (EXP) = (XSTR ((EXP), 1) == current_alternative_string \
357 ? true_rtx : false_rtx);
359 /* These are referenced by rtlanal.c and hence need to be defined somewhere.
360 They won't actually be used. */
362 rtx global_rtl
[GR_MAX
];
363 rtx pic_offset_table_rtx
;
365 static void attr_hash_add_rtx
PARAMS ((int, rtx
));
366 static void attr_hash_add_string
PARAMS ((int, char *));
367 static rtx attr_rtx
PARAMS ((enum rtx_code
, ...));
368 static rtx attr_rtx_1
PARAMS ((enum rtx_code
, va_list));
369 static char *attr_printf
PARAMS ((unsigned int, const char *, ...))
371 static char *attr_string
PARAMS ((const char *, int));
372 static rtx check_attr_test
PARAMS ((rtx
, int, int));
373 static rtx check_attr_value
PARAMS ((rtx
, struct attr_desc
*));
374 static rtx convert_set_attr_alternative
PARAMS ((rtx
, struct insn_def
*));
375 static rtx convert_set_attr
PARAMS ((rtx
, struct insn_def
*));
376 static void check_defs
PARAMS ((void));
378 static rtx convert_const_symbol_ref
PARAMS ((rtx
, struct attr_desc
*));
380 static rtx make_canonical
PARAMS ((struct attr_desc
*, rtx
));
381 static struct attr_value
*get_attr_value
PARAMS ((rtx
, struct attr_desc
*, int));
382 static rtx copy_rtx_unchanging
PARAMS ((rtx
));
383 static rtx copy_boolean
PARAMS ((rtx
));
384 static void expand_delays
PARAMS ((void));
385 static rtx operate_exp
PARAMS ((enum operator, rtx
, rtx
));
386 static void expand_units
PARAMS ((void));
387 static rtx simplify_knowing
PARAMS ((rtx
, rtx
));
388 static rtx encode_units_mask
PARAMS ((rtx
));
389 static void fill_attr
PARAMS ((struct attr_desc
*));
390 /* dpx2 compiler chokes if we specify the arg types of the args. */
391 static rtx substitute_address
PARAMS ((rtx
, rtx (*) (rtx
), rtx (*) (rtx
)));
392 static void make_length_attrs
PARAMS ((void));
393 static rtx identity_fn
PARAMS ((rtx
));
394 static rtx zero_fn
PARAMS ((rtx
));
395 static rtx one_fn
PARAMS ((rtx
));
396 static rtx max_fn
PARAMS ((rtx
));
397 static void write_length_unit_log
PARAMS ((void));
398 static rtx simplify_cond
PARAMS ((rtx
, int, int));
400 static rtx simplify_by_alternatives
PARAMS ((rtx
, int, int));
402 static rtx simplify_by_exploding
PARAMS ((rtx
));
403 static int find_and_mark_used_attributes
PARAMS ((rtx
, rtx
*, int *));
404 static void unmark_used_attributes
PARAMS ((rtx
, struct dimension
*, int));
405 static int add_values_to_cover
PARAMS ((struct dimension
*));
406 static int increment_current_value
PARAMS ((struct dimension
*, int));
407 static rtx test_for_current_value
PARAMS ((struct dimension
*, int));
408 static rtx simplify_with_current_value
PARAMS ((rtx
, struct dimension
*, int));
409 static rtx simplify_with_current_value_aux
PARAMS ((rtx
));
410 static void clear_struct_flag
PARAMS ((rtx
));
411 static int count_sub_rtxs
PARAMS ((rtx
, int));
412 static void remove_insn_ent
PARAMS ((struct attr_value
*, struct insn_ent
*));
413 static void insert_insn_ent
PARAMS ((struct attr_value
*, struct insn_ent
*));
414 static rtx insert_right_side
PARAMS ((enum rtx_code
, rtx
, rtx
, int, int));
415 static rtx make_alternative_compare
PARAMS ((int));
416 static int compute_alternative_mask
PARAMS ((rtx
, enum rtx_code
));
417 static rtx evaluate_eq_attr
PARAMS ((rtx
, rtx
, int, int));
418 static rtx simplify_and_tree
PARAMS ((rtx
, rtx
*, int, int));
419 static rtx simplify_or_tree
PARAMS ((rtx
, rtx
*, int, int));
420 static rtx simplify_test_exp
PARAMS ((rtx
, int, int));
421 static rtx simplify_test_exp_in_temp
PARAMS ((rtx
, int, int));
422 static void optimize_attrs
PARAMS ((void));
423 static void gen_attr
PARAMS ((rtx
, int));
424 static int count_alternatives
PARAMS ((rtx
));
425 static int compares_alternatives_p
PARAMS ((rtx
));
426 static int contained_in_p
PARAMS ((rtx
, rtx
));
427 static void gen_insn
PARAMS ((rtx
, int));
428 static void gen_delay
PARAMS ((rtx
, int));
429 static void gen_unit
PARAMS ((rtx
, int));
430 static void write_test_expr
PARAMS ((rtx
, int));
431 static int max_attr_value
PARAMS ((rtx
, int*));
432 static int or_attr_value
PARAMS ((rtx
, int*));
433 static void walk_attr_value
PARAMS ((rtx
));
434 static void write_attr_get
PARAMS ((struct attr_desc
*));
435 static rtx eliminate_known_true
PARAMS ((rtx
, rtx
, int, int));
436 static void write_attr_set
PARAMS ((struct attr_desc
*, int, rtx
,
437 const char *, const char *, rtx
,
439 static void write_attr_case
PARAMS ((struct attr_desc
*, struct attr_value
*,
440 int, const char *, const char *, int, rtx
));
441 static void write_unit_name
PARAMS ((const char *, int, const char *));
442 static void write_attr_valueq
PARAMS ((struct attr_desc
*, const char *));
443 static void write_attr_value
PARAMS ((struct attr_desc
*, rtx
));
444 static void write_upcase
PARAMS ((const char *));
445 static void write_indent
PARAMS ((int));
446 static void write_eligible_delay
PARAMS ((const char *));
447 static void write_function_unit_info
PARAMS ((void));
448 static void write_complex_function
PARAMS ((struct function_unit
*, const char *,
450 static int write_expr_attr_cache
PARAMS ((rtx
, struct attr_desc
*));
451 static void write_toplevel_expr
PARAMS ((rtx
));
452 static void write_const_num_delay_slots
PARAMS ((void));
453 static int n_comma_elts
PARAMS ((const char *));
454 static char *next_comma_elt
PARAMS ((const char **));
455 static struct attr_desc
*find_attr
PARAMS ((const char *, int));
456 static void make_internal_attr
PARAMS ((const char *, rtx
, int));
457 static struct attr_value
*find_most_used
PARAMS ((struct attr_desc
*));
458 static rtx find_single_value
PARAMS ((struct attr_desc
*));
459 static rtx make_numeric_value
PARAMS ((int));
460 static void extend_range
PARAMS ((struct range
*, int, int));
461 static rtx attr_eq
PARAMS ((const char *, const char *));
462 static const char *attr_numeral
PARAMS ((int));
463 static int attr_equal_p
PARAMS ((rtx
, rtx
));
464 static rtx attr_copy_rtx
PARAMS ((rtx
));
465 static int attr_rtx_cost
PARAMS ((rtx
));
467 #define oballoc(size) obstack_alloc (hash_obstack, size)
469 /* Hash table for sharing RTL and strings. */
471 /* Each hash table slot is a bucket containing a chain of these structures.
472 Strings are given negative hash codes; RTL expressions are given positive
477 struct attr_hash
*next
; /* Next structure in the bucket. */
478 int hashcode
; /* Hash code of this rtx or string. */
481 char *str
; /* The string (negative hash codes) */
482 rtx rtl
; /* or the RTL recorded here. */
486 /* Now here is the hash table. When recording an RTL, it is added to
487 the slot whose index is the hash code mod the table size. Note
488 that the hash table is used for several kinds of RTL (see attr_rtx)
489 and for strings. While all these live in the same table, they are
490 completely independent, and the hash code is computed differently
493 #define RTL_HASH_SIZE 4093
494 struct attr_hash
*attr_hash_table
[RTL_HASH_SIZE
];
496 /* Here is how primitive or already-shared RTL's hash
498 #define RTL_HASH(RTL) ((long) (RTL) & 0777777)
500 /* Add an entry to the hash table for RTL with hash code HASHCODE. */
503 attr_hash_add_rtx (hashcode
, rtl
)
509 h
= (struct attr_hash
*) obstack_alloc (hash_obstack
,
510 sizeof (struct attr_hash
));
511 h
->hashcode
= hashcode
;
513 h
->next
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
];
514 attr_hash_table
[hashcode
% RTL_HASH_SIZE
] = h
;
517 /* Add an entry to the hash table for STRING with hash code HASHCODE. */
520 attr_hash_add_string (hashcode
, str
)
526 h
= (struct attr_hash
*) obstack_alloc (hash_obstack
,
527 sizeof (struct attr_hash
));
528 h
->hashcode
= -hashcode
;
530 h
->next
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
];
531 attr_hash_table
[hashcode
% RTL_HASH_SIZE
] = h
;
534 /* Generate an RTL expression, but avoid duplicates.
535 Set the RTX_INTEGRATED_P flag for these permanent objects.
537 In some cases we cannot uniquify; then we return an ordinary
538 impermanent rtx with RTX_INTEGRATED_P clear.
540 Args are like gen_rtx, but without the mode:
542 rtx attr_rtx (code, [element1, ..., elementn]) */
549 rtx rt_val
= NULL_RTX
;/* RTX to return to caller... */
552 struct obstack
*old_obstack
= rtl_obstack
;
554 /* For each of several cases, search the hash table for an existing entry.
555 Use that entry if one is found; otherwise create a new RTL and add it
558 if (GET_RTX_CLASS (code
) == '1')
560 rtx arg0
= va_arg (p
, rtx
);
562 /* A permanent object cannot point to impermanent ones. */
563 if (! RTX_INTEGRATED_P (arg0
))
565 rt_val
= rtx_alloc (code
);
566 XEXP (rt_val
, 0) = arg0
;
570 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
));
571 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
572 if (h
->hashcode
== hashcode
573 && GET_CODE (h
->u
.rtl
) == code
574 && XEXP (h
->u
.rtl
, 0) == arg0
)
579 rtl_obstack
= hash_obstack
;
580 rt_val
= rtx_alloc (code
);
581 XEXP (rt_val
, 0) = arg0
;
584 else if (GET_RTX_CLASS (code
) == 'c'
585 || GET_RTX_CLASS (code
) == '2'
586 || GET_RTX_CLASS (code
) == '<')
588 rtx arg0
= va_arg (p
, rtx
);
589 rtx arg1
= va_arg (p
, rtx
);
591 /* A permanent object cannot point to impermanent ones. */
592 if (! RTX_INTEGRATED_P (arg0
) || ! RTX_INTEGRATED_P (arg1
))
594 rt_val
= rtx_alloc (code
);
595 XEXP (rt_val
, 0) = arg0
;
596 XEXP (rt_val
, 1) = arg1
;
600 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
) + RTL_HASH (arg1
));
601 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
602 if (h
->hashcode
== hashcode
603 && GET_CODE (h
->u
.rtl
) == code
604 && XEXP (h
->u
.rtl
, 0) == arg0
605 && XEXP (h
->u
.rtl
, 1) == arg1
)
610 rtl_obstack
= hash_obstack
;
611 rt_val
= rtx_alloc (code
);
612 XEXP (rt_val
, 0) = arg0
;
613 XEXP (rt_val
, 1) = arg1
;
616 else if (GET_RTX_LENGTH (code
) == 1
617 && GET_RTX_FORMAT (code
)[0] == 's')
619 char *arg0
= va_arg (p
, char *);
621 if (code
== SYMBOL_REF
)
622 arg0
= attr_string (arg0
, strlen (arg0
));
624 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
));
625 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
626 if (h
->hashcode
== hashcode
627 && GET_CODE (h
->u
.rtl
) == code
628 && XSTR (h
->u
.rtl
, 0) == arg0
)
633 rtl_obstack
= hash_obstack
;
634 rt_val
= rtx_alloc (code
);
635 XSTR (rt_val
, 0) = arg0
;
638 else if (GET_RTX_LENGTH (code
) == 2
639 && GET_RTX_FORMAT (code
)[0] == 's'
640 && GET_RTX_FORMAT (code
)[1] == 's')
642 char *arg0
= va_arg (p
, char *);
643 char *arg1
= va_arg (p
, char *);
645 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
) + RTL_HASH (arg1
));
646 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
647 if (h
->hashcode
== hashcode
648 && GET_CODE (h
->u
.rtl
) == code
649 && XSTR (h
->u
.rtl
, 0) == arg0
650 && XSTR (h
->u
.rtl
, 1) == arg1
)
655 rtl_obstack
= hash_obstack
;
656 rt_val
= rtx_alloc (code
);
657 XSTR (rt_val
, 0) = arg0
;
658 XSTR (rt_val
, 1) = arg1
;
661 else if (code
== CONST_INT
)
663 HOST_WIDE_INT arg0
= va_arg (p
, HOST_WIDE_INT
);
673 int i
; /* Array indices... */
674 const char *fmt
; /* Current rtx's format... */
676 rt_val
= rtx_alloc (code
); /* Allocate the storage space. */
678 fmt
= GET_RTX_FORMAT (code
); /* Find the right format... */
679 for (i
= 0; i
< GET_RTX_LENGTH (code
); i
++)
683 case '0': /* Unused field. */
686 case 'i': /* An integer? */
687 XINT (rt_val
, i
) = va_arg (p
, int);
690 case 'w': /* A wide integer? */
691 XWINT (rt_val
, i
) = va_arg (p
, HOST_WIDE_INT
);
694 case 's': /* A string? */
695 XSTR (rt_val
, i
) = va_arg (p
, char *);
698 case 'e': /* An expression? */
699 case 'u': /* An insn? Same except when printing. */
700 XEXP (rt_val
, i
) = va_arg (p
, rtx
);
703 case 'E': /* An RTX vector? */
704 XVEC (rt_val
, i
) = va_arg (p
, rtvec
);
714 rtl_obstack
= old_obstack
;
715 attr_hash_add_rtx (hashcode
, rt_val
);
716 RTX_INTEGRATED_P (rt_val
) = 1;
721 attr_rtx
VPARAMS ((enum rtx_code code
, ...))
726 VA_FIXEDARG (p
, enum rtx_code
, code
);
727 result
= attr_rtx_1 (code
, p
);
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]) */
738 attr_printf
VPARAMS ((unsigned int len
, const char *fmt
, ...))
743 VA_FIXEDARG (p
, unsigned int, len
);
744 VA_FIXEDARG (p
, const char *, fmt
);
746 if (len
> sizeof str
- 1) /* Leave room for \0. */
749 vsprintf (str
, fmt
, p
);
752 return attr_string (str
, strlen (str
));
756 attr_eq (name
, value
)
757 const char *name
, *value
;
759 return attr_rtx (EQ_ATTR
, attr_string (name
, strlen (name
)),
760 attr_string (value
, strlen (value
)));
767 return XSTR (make_numeric_value (n
), 0);
770 /* Return a permanent (possibly shared) copy of a string STR (not assumed
771 to be null terminated) with LEN bytes. */
774 attr_string (str
, len
)
783 /* Compute the hash code. */
784 hashcode
= (len
+ 1) * 613 + (unsigned) str
[0];
785 for (i
= 1; i
<= len
; i
+= 2)
786 hashcode
= ((hashcode
* 613) + (unsigned) str
[i
]);
788 hashcode
= -hashcode
;
790 /* Search the table for the string. */
791 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
792 if (h
->hashcode
== -hashcode
&& h
->u
.str
[0] == str
[0]
793 && !strncmp (h
->u
.str
, str
, len
))
794 return h
->u
.str
; /* <-- return if found. */
796 /* Not found; create a permanent copy and add it to the hash table. */
797 new_str
= (char *) obstack_alloc (hash_obstack
, len
+ 1);
798 memcpy (new_str
, str
, len
);
800 attr_hash_add_string (hashcode
, new_str
);
802 return new_str
; /* Return the new string. */
805 /* Check two rtx's for equality of contents,
806 taking advantage of the fact that if both are hashed
807 then they can't be equal unless they are the same object. */
813 return (x
== y
|| (! (RTX_INTEGRATED_P (x
) && RTX_INTEGRATED_P (y
))
814 && rtx_equal_p (x
, y
)));
817 /* Copy an attribute value expression,
818 descending to all depths, but not copying any
819 permanent hashed subexpressions. */
828 const char *format_ptr
;
830 /* No need to copy a permanent object. */
831 if (RTX_INTEGRATED_P (orig
))
834 code
= GET_CODE (orig
);
852 copy
= rtx_alloc (code
);
853 PUT_MODE (copy
, GET_MODE (orig
));
854 copy
->in_struct
= orig
->in_struct
;
855 copy
->volatil
= orig
->volatil
;
856 copy
->unchanging
= orig
->unchanging
;
857 copy
->integrated
= orig
->integrated
;
859 format_ptr
= GET_RTX_FORMAT (GET_CODE (copy
));
861 for (i
= 0; i
< GET_RTX_LENGTH (GET_CODE (copy
)); i
++)
863 switch (*format_ptr
++)
866 XEXP (copy
, i
) = XEXP (orig
, i
);
867 if (XEXP (orig
, i
) != NULL
)
868 XEXP (copy
, i
) = attr_copy_rtx (XEXP (orig
, i
));
873 XVEC (copy
, i
) = XVEC (orig
, i
);
874 if (XVEC (orig
, i
) != NULL
)
876 XVEC (copy
, i
) = rtvec_alloc (XVECLEN (orig
, i
));
877 for (j
= 0; j
< XVECLEN (copy
, i
); j
++)
878 XVECEXP (copy
, i
, j
) = attr_copy_rtx (XVECEXP (orig
, i
, j
));
884 XINT (copy
, i
) = XINT (orig
, i
);
888 XWINT (copy
, i
) = XWINT (orig
, i
);
893 XSTR (copy
, i
) = XSTR (orig
, i
);
903 /* Given a test expression for an attribute, ensure it is validly formed.
904 IS_CONST indicates whether the expression is constant for each compiler
905 run (a constant expression may not test any particular insn).
907 Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
908 and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
909 test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
911 Update the string address in EQ_ATTR expression to be the same used
912 in the attribute (or `alternative_name') to speed up subsequent
913 `find_attr' calls and eliminate most `strcmp' calls.
915 Return the new expression, if any. */
918 check_attr_test (exp
, is_const
, lineno
)
923 struct attr_desc
*attr
;
924 struct attr_value
*av
;
925 const char *name_ptr
, *p
;
928 switch (GET_CODE (exp
))
931 /* Handle negation test. */
932 if (XSTR (exp
, 1)[0] == '!')
933 return check_attr_test (attr_rtx (NOT
,
934 attr_eq (XSTR (exp
, 0),
938 else if (n_comma_elts (XSTR (exp
, 1)) == 1)
940 attr
= find_attr (XSTR (exp
, 0), 0);
943 if (! strcmp (XSTR (exp
, 0), "alternative"))
945 XSTR (exp
, 0) = alternative_name
;
946 /* This can't be simplified any further. */
947 RTX_UNCHANGING_P (exp
) = 1;
951 fatal ("unknown attribute `%s' in EQ_ATTR", XSTR (exp
, 0));
954 if (is_const
&& ! attr
->is_const
)
955 fatal ("constant expression uses insn attribute `%s' in EQ_ATTR",
958 /* Copy this just to make it permanent,
959 so expressions using it can be permanent too. */
960 exp
= attr_eq (XSTR (exp
, 0), XSTR (exp
, 1));
962 /* It shouldn't be possible to simplify the value given to a
963 constant attribute, so don't expand this until it's time to
964 write the test expression. */
966 RTX_UNCHANGING_P (exp
) = 1;
968 if (attr
->is_numeric
)
970 for (p
= XSTR (exp
, 1); *p
; p
++)
972 fatal ("attribute `%s' takes only numeric values",
977 for (av
= attr
->first_value
; av
; av
= av
->next
)
978 if (GET_CODE (av
->value
) == CONST_STRING
979 && ! strcmp (XSTR (exp
, 1), XSTR (av
->value
, 0)))
983 fatal ("unknown value `%s' for `%s' attribute",
984 XSTR (exp
, 1), XSTR (exp
, 0));
989 /* Make an IOR tree of the possible values. */
991 name_ptr
= XSTR (exp
, 1);
992 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
994 newexp
= attr_eq (XSTR (exp
, 0), p
);
995 orexp
= insert_right_side (IOR
, orexp
, newexp
, -2, -2);
998 return check_attr_test (orexp
, is_const
, lineno
);
1006 /* Either TRUE or FALSE. */
1014 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0), is_const
, lineno
);
1015 XEXP (exp
, 1) = check_attr_test (XEXP (exp
, 1), is_const
, lineno
);
1019 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0), is_const
, lineno
);
1025 fatal ("RTL operator \"%s\" not valid in constant attribute test",
1026 GET_RTX_NAME (GET_CODE (exp
)));
1027 /* These cases can't be simplified. */
1028 RTX_UNCHANGING_P (exp
) = 1;
1031 case LE
: case LT
: case GT
: case GE
:
1032 case LEU
: case LTU
: case GTU
: case GEU
:
1034 if (GET_CODE (XEXP (exp
, 0)) == SYMBOL_REF
1035 && GET_CODE (XEXP (exp
, 1)) == SYMBOL_REF
)
1036 exp
= attr_rtx (GET_CODE (exp
),
1037 attr_rtx (SYMBOL_REF
, XSTR (XEXP (exp
, 0), 0)),
1038 attr_rtx (SYMBOL_REF
, XSTR (XEXP (exp
, 1), 0)));
1039 /* These cases can't be simplified. */
1040 RTX_UNCHANGING_P (exp
) = 1;
1046 /* These cases are valid for constant attributes, but can't be
1048 exp
= attr_rtx (SYMBOL_REF
, XSTR (exp
, 0));
1049 RTX_UNCHANGING_P (exp
) = 1;
1053 fatal ("RTL operator \"%s\" not valid in attribute test",
1054 GET_RTX_NAME (GET_CODE (exp
)));
1060 /* Given an expression, ensure that it is validly formed and that all named
1061 attribute values are valid for the given attribute. Issue a fatal error
1062 if not. If no attribute is specified, assume a numeric attribute.
1064 Return a perhaps modified replacement expression for the value. */
1067 check_attr_value (exp
, attr
)
1069 struct attr_desc
*attr
;
1071 struct attr_value
*av
;
1075 switch (GET_CODE (exp
))
1078 if (attr
&& ! attr
->is_numeric
)
1080 message_with_line (attr
->lineno
,
1081 "CONST_INT not valid for non-numeric attribute %s",
1087 if (INTVAL (exp
) < 0 && ! attr
->negative_ok
)
1089 message_with_line (attr
->lineno
,
1090 "negative numeric value specified for attribute %s",
1098 if (! strcmp (XSTR (exp
, 0), "*"))
1101 if (attr
== 0 || attr
->is_numeric
)
1104 if (attr
&& attr
->negative_ok
&& *p
== '-')
1109 message_with_line (attr
? attr
->lineno
: 0,
1110 "non-numeric value for numeric attribute %s",
1111 attr
? attr
->name
: "internal");
1118 for (av
= attr
->first_value
; av
; av
= av
->next
)
1119 if (GET_CODE (av
->value
) == CONST_STRING
1120 && ! strcmp (XSTR (av
->value
, 0), XSTR (exp
, 0)))
1125 message_with_line (attr
->lineno
,
1126 "unknown value `%s' for `%s' attribute",
1127 XSTR (exp
, 0), attr
? attr
->name
: "internal");
1133 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0),
1134 attr
? attr
->is_const
: 0,
1135 attr
? attr
->lineno
: 0);
1136 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
1137 XEXP (exp
, 2) = check_attr_value (XEXP (exp
, 2), attr
);
1145 if (attr
&& !attr
->is_numeric
)
1147 message_with_line (attr
->lineno
,
1148 "invalid operation `%s' for non-numeric attribute value",
1149 GET_RTX_NAME (GET_CODE (exp
)));
1157 XEXP (exp
, 0) = check_attr_value (XEXP (exp
, 0), attr
);
1158 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
1162 XEXP (exp
, 0) = check_attr_value (XEXP (exp
, 0), attr
);
1166 if (XVECLEN (exp
, 0) % 2 != 0)
1168 message_with_line (attr
->lineno
,
1169 "first operand of COND must have even length");
1174 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1176 XVECEXP (exp
, 0, i
) = check_attr_test (XVECEXP (exp
, 0, i
),
1177 attr
? attr
->is_const
: 0,
1178 attr
? attr
->lineno
: 0);
1179 XVECEXP (exp
, 0, i
+ 1)
1180 = check_attr_value (XVECEXP (exp
, 0, i
+ 1), attr
);
1183 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
1188 struct attr_desc
*attr2
= find_attr (XSTR (exp
, 0), 0);
1191 message_with_line (attr
? attr
->lineno
: 0,
1192 "unknown attribute `%s' in ATTR",
1196 else if (attr
&& attr
->is_const
&& ! attr2
->is_const
)
1198 message_with_line (attr
->lineno
,
1199 "non-constant attribute `%s' referenced from `%s'",
1200 XSTR (exp
, 0), attr
->name
);
1204 && (attr
->is_numeric
!= attr2
->is_numeric
1205 || (! attr
->negative_ok
&& attr2
->negative_ok
)))
1207 message_with_line (attr
->lineno
,
1208 "numeric attribute mismatch calling `%s' from `%s'",
1209 XSTR (exp
, 0), attr
->name
);
1216 /* A constant SYMBOL_REF is valid as a constant attribute test and
1217 is expanded later by make_canonical into a COND. In a non-constant
1218 attribute test, it is left be. */
1219 return attr_rtx (SYMBOL_REF
, XSTR (exp
, 0));
1222 message_with_line (attr
? attr
->lineno
: 0,
1223 "invalid operation `%s' for attribute value",
1224 GET_RTX_NAME (GET_CODE (exp
)));
1232 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
1233 It becomes a COND with each test being (eq_attr "alternative "n") */
1236 convert_set_attr_alternative (exp
, id
)
1238 struct insn_def
*id
;
1240 int num_alt
= id
->num_alternatives
;
1244 if (XVECLEN (exp
, 1) != num_alt
)
1246 message_with_line (id
->lineno
,
1247 "bad number of entries in SET_ATTR_ALTERNATIVE");
1252 /* Make a COND with all tests but the last. Select the last value via the
1254 condexp
= rtx_alloc (COND
);
1255 XVEC (condexp
, 0) = rtvec_alloc ((num_alt
- 1) * 2);
1257 for (i
= 0; i
< num_alt
- 1; i
++)
1260 p
= attr_numeral (i
);
1262 XVECEXP (condexp
, 0, 2 * i
) = attr_eq (alternative_name
, p
);
1263 XVECEXP (condexp
, 0, 2 * i
+ 1) = XVECEXP (exp
, 1, i
);
1266 XEXP (condexp
, 1) = XVECEXP (exp
, 1, i
);
1268 return attr_rtx (SET
, attr_rtx (ATTR
, XSTR (exp
, 0)), condexp
);
1271 /* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
1272 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
1275 convert_set_attr (exp
, id
)
1277 struct insn_def
*id
;
1280 const char *name_ptr
;
1284 /* See how many alternative specified. */
1285 n
= n_comma_elts (XSTR (exp
, 1));
1287 return attr_rtx (SET
,
1288 attr_rtx (ATTR
, XSTR (exp
, 0)),
1289 attr_rtx (CONST_STRING
, XSTR (exp
, 1)));
1291 newexp
= rtx_alloc (SET_ATTR_ALTERNATIVE
);
1292 XSTR (newexp
, 0) = XSTR (exp
, 0);
1293 XVEC (newexp
, 1) = rtvec_alloc (n
);
1295 /* Process each comma-separated name. */
1296 name_ptr
= XSTR (exp
, 1);
1298 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
1299 XVECEXP (newexp
, 1, n
++) = attr_rtx (CONST_STRING
, p
);
1301 return convert_set_attr_alternative (newexp
, id
);
1304 /* Scan all definitions, checking for validity. Also, convert any SET_ATTR
1305 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
1311 struct insn_def
*id
;
1312 struct attr_desc
*attr
;
1316 for (id
= defs
; id
; id
= id
->next
)
1318 if (XVEC (id
->def
, id
->vec_idx
) == NULL
)
1321 for (i
= 0; i
< XVECLEN (id
->def
, id
->vec_idx
); i
++)
1323 value
= XVECEXP (id
->def
, id
->vec_idx
, i
);
1324 switch (GET_CODE (value
))
1327 if (GET_CODE (XEXP (value
, 0)) != ATTR
)
1329 message_with_line (id
->lineno
, "bad attribute set");
1335 case SET_ATTR_ALTERNATIVE
:
1336 value
= convert_set_attr_alternative (value
, id
);
1340 value
= convert_set_attr (value
, id
);
1344 message_with_line (id
->lineno
, "invalid attribute code %s",
1345 GET_RTX_NAME (GET_CODE (value
)));
1349 if (value
== NULL_RTX
)
1352 if ((attr
= find_attr (XSTR (XEXP (value
, 0), 0), 0)) == NULL
)
1354 message_with_line (id
->lineno
, "unknown attribute %s",
1355 XSTR (XEXP (value
, 0), 0));
1360 XVECEXP (id
->def
, id
->vec_idx
, i
) = value
;
1361 XEXP (value
, 1) = check_attr_value (XEXP (value
, 1), attr
);
1367 /* Given a constant SYMBOL_REF expression, convert to a COND that
1368 explicitly tests each enumerated value. */
1371 convert_const_symbol_ref (exp
, attr
)
1373 struct attr_desc
*attr
;
1376 struct attr_value
*av
;
1380 for (av
= attr
->first_value
; av
; av
= av
->next
)
1383 /* Make a COND with all tests but the last, and in the original order.
1384 Select the last value via the default. Note that the attr values
1385 are constructed in reverse order. */
1387 condexp
= rtx_alloc (COND
);
1388 XVEC (condexp
, 0) = rtvec_alloc ((num_alt
- 1) * 2);
1389 av
= attr
->first_value
;
1390 XEXP (condexp
, 1) = av
->value
;
1392 for (i
= num_alt
- 2; av
= av
->next
, i
>= 0; i
--)
1397 string
= p
= (char *) oballoc (2
1398 + strlen (attr
->name
)
1399 + strlen (XSTR (av
->value
, 0)));
1400 strcpy (p
, attr
->name
);
1402 strcat (p
, XSTR (av
->value
, 0));
1403 for (; *p
!= '\0'; p
++)
1406 value
= attr_rtx (SYMBOL_REF
, string
);
1407 RTX_UNCHANGING_P (value
) = 1;
1409 XVECEXP (condexp
, 0, 2 * i
) = attr_rtx (EQ
, exp
, value
);
1411 XVECEXP (condexp
, 0, 2 * i
+ 1) = av
->value
;
1418 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1419 expressions by converting them into a COND. This removes cases from this
1420 program. Also, replace an attribute value of "*" with the default attribute
1424 make_canonical (attr
, exp
)
1425 struct attr_desc
*attr
;
1431 switch (GET_CODE (exp
))
1434 exp
= make_numeric_value (INTVAL (exp
));
1438 if (! strcmp (XSTR (exp
, 0), "*"))
1440 if (attr
== 0 || attr
->default_val
== 0)
1441 fatal ("(attr_value \"*\") used in invalid context");
1442 exp
= attr
->default_val
->value
;
1448 if (!attr
->is_const
|| RTX_UNCHANGING_P (exp
))
1450 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1451 This makes the COND something that won't be considered an arbitrary
1452 expression by walk_attr_value. */
1453 RTX_UNCHANGING_P (exp
) = 1;
1455 /* ??? Why do we do this? With attribute values { A B C D E }, this
1456 tends to generate (!(x==A) && !(x==B) && !(x==C) && !(x==D)) rather
1458 exp
= convert_const_symbol_ref (exp
, attr
);
1459 RTX_UNCHANGING_P (exp
) = 1;
1460 exp
= check_attr_value (exp
, attr
);
1461 /* Goto COND case since this is now a COND. Note that while the
1462 new expression is rescanned, all symbol_ref notes are marked as
1466 exp
= check_attr_value (exp
, attr
);
1471 newexp
= rtx_alloc (COND
);
1472 XVEC (newexp
, 0) = rtvec_alloc (2);
1473 XVECEXP (newexp
, 0, 0) = XEXP (exp
, 0);
1474 XVECEXP (newexp
, 0, 1) = XEXP (exp
, 1);
1476 XEXP (newexp
, 1) = XEXP (exp
, 2);
1479 /* Fall through to COND case since this is now a COND. */
1486 /* First, check for degenerate COND. */
1487 if (XVECLEN (exp
, 0) == 0)
1488 return make_canonical (attr
, XEXP (exp
, 1));
1489 defval
= XEXP (exp
, 1) = make_canonical (attr
, XEXP (exp
, 1));
1491 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1493 XVECEXP (exp
, 0, i
) = copy_boolean (XVECEXP (exp
, 0, i
));
1494 XVECEXP (exp
, 0, i
+ 1)
1495 = make_canonical (attr
, XVECEXP (exp
, 0, i
+ 1));
1496 if (! rtx_equal_p (XVECEXP (exp
, 0, i
+ 1), defval
))
1515 if (GET_CODE (exp
) == AND
|| GET_CODE (exp
) == IOR
)
1516 return attr_rtx (GET_CODE (exp
), copy_boolean (XEXP (exp
, 0)),
1517 copy_boolean (XEXP (exp
, 1)));
1521 /* Given a value and an attribute description, return a `struct attr_value *'
1522 that represents that value. This is either an existing structure, if the
1523 value has been previously encountered, or a newly-created structure.
1525 `insn_code' is the code of an insn whose attribute has the specified
1526 value (-2 if not processing an insn). We ensure that all insns for
1527 a given value have the same number of alternatives if the value checks
1530 static struct attr_value
*
1531 get_attr_value (value
, attr
, insn_code
)
1533 struct attr_desc
*attr
;
1536 struct attr_value
*av
;
1539 value
= make_canonical (attr
, value
);
1540 if (compares_alternatives_p (value
))
1542 if (insn_code
< 0 || insn_alternatives
== NULL
)
1543 fatal ("(eq_attr \"alternatives\" ...) used in non-insn context");
1545 num_alt
= insn_alternatives
[insn_code
];
1548 for (av
= attr
->first_value
; av
; av
= av
->next
)
1549 if (rtx_equal_p (value
, av
->value
)
1550 && (num_alt
== 0 || av
->first_insn
== NULL
1551 || insn_alternatives
[av
->first_insn
->insn_code
]))
1554 av
= (struct attr_value
*) oballoc (sizeof (struct attr_value
));
1556 av
->next
= attr
->first_value
;
1557 attr
->first_value
= av
;
1558 av
->first_insn
= NULL
;
1560 av
->has_asm_insn
= 0;
1565 /* After all DEFINE_DELAYs have been read in, create internal attributes
1566 to generate the required routines.
1568 First, we compute the number of delay slots for each insn (as a COND of
1569 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1570 delay type is specified, we compute a similar function giving the
1571 DEFINE_DELAY ordinal for each insn.
1573 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1574 tells whether a given insn can be in that delay slot.
1576 Normal attribute filling and optimization expands these to contain the
1577 information needed to handle delay slots. */
1582 struct delay_desc
*delay
;
1588 /* First, generate data for `num_delay_slots' function. */
1590 condexp
= rtx_alloc (COND
);
1591 XVEC (condexp
, 0) = rtvec_alloc (num_delays
* 2);
1592 XEXP (condexp
, 1) = make_numeric_value (0);
1594 for (i
= 0, delay
= delays
; delay
; i
+= 2, delay
= delay
->next
)
1596 XVECEXP (condexp
, 0, i
) = XEXP (delay
->def
, 0);
1597 XVECEXP (condexp
, 0, i
+ 1)
1598 = make_numeric_value (XVECLEN (delay
->def
, 1) / 3);
1601 make_internal_attr ("*num_delay_slots", condexp
, 0);
1603 /* If more than one delay type, do the same for computing the delay type. */
1606 condexp
= rtx_alloc (COND
);
1607 XVEC (condexp
, 0) = rtvec_alloc (num_delays
* 2);
1608 XEXP (condexp
, 1) = make_numeric_value (0);
1610 for (i
= 0, delay
= delays
; delay
; i
+= 2, delay
= delay
->next
)
1612 XVECEXP (condexp
, 0, i
) = XEXP (delay
->def
, 0);
1613 XVECEXP (condexp
, 0, i
+ 1) = make_numeric_value (delay
->num
);
1616 make_internal_attr ("*delay_type", condexp
, 1);
1619 /* For each delay possibility and delay slot, compute an eligibility
1620 attribute for non-annulled insns and for each type of annulled (annul
1621 if true and annul if false). */
1622 for (delay
= delays
; delay
; delay
= delay
->next
)
1624 for (i
= 0; i
< XVECLEN (delay
->def
, 1); i
+= 3)
1626 condexp
= XVECEXP (delay
->def
, 1, i
);
1628 condexp
= false_rtx
;
1629 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1630 make_numeric_value (1), make_numeric_value (0));
1632 p
= attr_printf (sizeof "*delay__" + MAX_DIGITS
* 2,
1633 "*delay_%d_%d", delay
->num
, i
/ 3);
1634 make_internal_attr (p
, newexp
, 1);
1636 if (have_annul_true
)
1638 condexp
= XVECEXP (delay
->def
, 1, i
+ 1);
1639 if (condexp
== 0) condexp
= false_rtx
;
1640 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1641 make_numeric_value (1),
1642 make_numeric_value (0));
1643 p
= attr_printf (sizeof "*annul_true__" + MAX_DIGITS
* 2,
1644 "*annul_true_%d_%d", delay
->num
, i
/ 3);
1645 make_internal_attr (p
, newexp
, 1);
1648 if (have_annul_false
)
1650 condexp
= XVECEXP (delay
->def
, 1, i
+ 2);
1651 if (condexp
== 0) condexp
= false_rtx
;
1652 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1653 make_numeric_value (1),
1654 make_numeric_value (0));
1655 p
= attr_printf (sizeof "*annul_false__" + MAX_DIGITS
* 2,
1656 "*annul_false_%d_%d", delay
->num
, i
/ 3);
1657 make_internal_attr (p
, newexp
, 1);
1663 /* This function is given a left and right side expression and an operator.
1664 Each side is a conditional expression, each alternative of which has a
1665 numerical value. The function returns another conditional expression
1666 which, for every possible set of condition values, returns a value that is
1667 the operator applied to the values of the two sides.
1669 Since this is called early, it must also support IF_THEN_ELSE. */
1672 operate_exp (op
, left
, right
)
1676 int left_value
, right_value
;
1680 /* If left is a string, apply operator to it and the right side. */
1681 if (GET_CODE (left
) == CONST_STRING
)
1683 /* If right is also a string, just perform the operation. */
1684 if (GET_CODE (right
) == CONST_STRING
)
1686 left_value
= atoi (XSTR (left
, 0));
1687 right_value
= atoi (XSTR (right
, 0));
1691 i
= left_value
+ right_value
;
1695 i
= left_value
- right_value
;
1698 case POS_MINUS_OP
: /* The positive part of LEFT - RIGHT. */
1699 if (left_value
> right_value
)
1700 i
= left_value
- right_value
;
1707 i
= left_value
| right_value
;
1711 i
= left_value
== right_value
;
1715 i
= (left_value
<< (HOST_BITS_PER_INT
/ 2)) | right_value
;
1719 if (left_value
> right_value
)
1726 if (left_value
< right_value
)
1736 if (i
== left_value
)
1738 if (i
== right_value
)
1740 return make_numeric_value (i
);
1742 else if (GET_CODE (right
) == IF_THEN_ELSE
)
1744 /* Apply recursively to all values within. */
1745 rtx newleft
= operate_exp (op
, left
, XEXP (right
, 1));
1746 rtx newright
= operate_exp (op
, left
, XEXP (right
, 2));
1747 if (rtx_equal_p (newleft
, newright
))
1749 return attr_rtx (IF_THEN_ELSE
, XEXP (right
, 0), newleft
, newright
);
1751 else if (GET_CODE (right
) == COND
)
1756 newexp
= rtx_alloc (COND
);
1757 XVEC (newexp
, 0) = rtvec_alloc (XVECLEN (right
, 0));
1758 defval
= XEXP (newexp
, 1) = operate_exp (op
, left
, XEXP (right
, 1));
1760 for (i
= 0; i
< XVECLEN (right
, 0); i
+= 2)
1762 XVECEXP (newexp
, 0, i
) = XVECEXP (right
, 0, i
);
1763 XVECEXP (newexp
, 0, i
+ 1)
1764 = operate_exp (op
, left
, XVECEXP (right
, 0, i
+ 1));
1765 if (! rtx_equal_p (XVECEXP (newexp
, 0, i
+ 1),
1770 /* If the resulting cond is trivial (all alternatives
1771 give the same value), optimize it away. */
1773 return operate_exp (op
, left
, XEXP (right
, 1));
1778 fatal ("badly formed attribute value");
1781 /* A hack to prevent expand_units from completely blowing up: ORX_OP does
1782 not associate through IF_THEN_ELSE. */
1783 else if (op
== ORX_OP
&& GET_CODE (right
) == IF_THEN_ELSE
)
1785 return attr_rtx (IOR
, left
, right
);
1788 /* Otherwise, do recursion the other way. */
1789 else if (GET_CODE (left
) == IF_THEN_ELSE
)
1791 rtx newleft
= operate_exp (op
, XEXP (left
, 1), right
);
1792 rtx newright
= operate_exp (op
, XEXP (left
, 2), right
);
1793 if (rtx_equal_p (newleft
, newright
))
1795 return attr_rtx (IF_THEN_ELSE
, XEXP (left
, 0), newleft
, newright
);
1797 else if (GET_CODE (left
) == COND
)
1802 newexp
= rtx_alloc (COND
);
1803 XVEC (newexp
, 0) = rtvec_alloc (XVECLEN (left
, 0));
1804 defval
= XEXP (newexp
, 1) = operate_exp (op
, XEXP (left
, 1), right
);
1806 for (i
= 0; i
< XVECLEN (left
, 0); i
+= 2)
1808 XVECEXP (newexp
, 0, i
) = XVECEXP (left
, 0, i
);
1809 XVECEXP (newexp
, 0, i
+ 1)
1810 = operate_exp (op
, XVECEXP (left
, 0, i
+ 1), right
);
1811 if (! rtx_equal_p (XVECEXP (newexp
, 0, i
+ 1),
1816 /* If the cond is trivial (all alternatives give the same value),
1817 optimize it away. */
1819 return operate_exp (op
, XEXP (left
, 1), right
);
1821 /* If the result is the same as the LEFT operand,
1823 if (rtx_equal_p (newexp
, left
))
1830 fatal ("badly formed attribute value");
1835 /* Once all attributes and DEFINE_FUNCTION_UNITs have been read, we
1836 construct a number of attributes.
1838 The first produces a function `function_units_used' which is given an
1839 insn and produces an encoding showing which function units are required
1840 for the execution of that insn. If the value is non-negative, the insn
1841 uses that unit; otherwise, the value is a one's compliment mask of units
1844 The second produces a function `result_ready_cost' which is used to
1845 determine the time that the result of an insn will be ready and hence
1846 a worst-case schedule.
1848 Both of these produce quite complex expressions which are then set as the
1849 default value of internal attributes. Normal attribute simplification
1850 should produce reasonable expressions.
1852 For each unit, a `<name>_unit_ready_cost' function will take an
1853 insn and give the delay until that unit will be ready with the result
1854 and a `<name>_unit_conflict_cost' function is given an insn already
1855 executing on the unit and a candidate to execute and will give the
1856 cost from the time the executing insn started until the candidate
1857 can start (ignore limitations on the number of simultaneous insns).
1859 For each unit, a `<name>_unit_blockage' function is given an insn
1860 already executing on the unit and a candidate to execute and will
1861 give the delay incurred due to function unit conflicts. The range of
1862 blockage cost values for a given executing insn is given by the
1863 `<name>_unit_blockage_range' function. These values are encoded in
1864 an int where the upper half gives the minimum value and the lower
1865 half gives the maximum value. */
1870 struct function_unit
*unit
, **unit_num
;
1871 struct function_unit_op
*op
, **op_array
, ***unit_ops
;
1876 int i
, j
, u
, num
, nvalues
;
1878 /* Rebuild the condition for the unit to share the RTL expressions.
1879 Sharing is required by simplify_by_exploding. Build the issue delay
1880 expressions. Validate the expressions we were given for the conditions
1881 and conflict vector. Then make attributes for use in the conflict
1884 for (unit
= units
; unit
; unit
= unit
->next
)
1886 unit
->condexp
= check_attr_test (unit
->condexp
, 0, unit
->first_lineno
);
1888 for (op
= unit
->ops
; op
; op
= op
->next
)
1890 rtx issue_delay
= make_numeric_value (op
->issue_delay
);
1891 rtx issue_exp
= issue_delay
;
1893 /* Build, validate, and simplify the issue delay expression. */
1894 if (op
->conflict_exp
!= true_rtx
)
1895 issue_exp
= attr_rtx (IF_THEN_ELSE
, op
->conflict_exp
,
1896 issue_exp
, make_numeric_value (0));
1897 issue_exp
= check_attr_value (make_canonical (NULL_ATTR
,
1900 issue_exp
= simplify_knowing (issue_exp
, unit
->condexp
);
1901 op
->issue_exp
= issue_exp
;
1903 /* Make an attribute for use in the conflict function if needed. */
1904 unit
->needs_conflict_function
= (unit
->issue_delay
.min
1905 != unit
->issue_delay
.max
);
1906 if (unit
->needs_conflict_function
)
1908 str
= attr_printf ((strlen (unit
->name
) + sizeof "*_cost_"
1910 "*%s_cost_%d", unit
->name
, op
->num
);
1911 make_internal_attr (str
, issue_exp
, 1);
1914 /* Validate the condition. */
1915 op
->condexp
= check_attr_test (op
->condexp
, 0, op
->lineno
);
1919 /* Compute the mask of function units used. Initially, the unitsmask is
1920 zero. Set up a conditional to compute each unit's contribution. */
1921 unitsmask
= make_numeric_value (0);
1922 newexp
= rtx_alloc (IF_THEN_ELSE
);
1923 XEXP (newexp
, 2) = make_numeric_value (0);
1925 /* If we have just a few units, we may be all right expanding the whole
1926 thing. But the expansion is 2**N in space on the number of opclasses,
1927 so we can't do this for very long -- Alpha and MIPS in particular have
1928 problems with this. So in that situation, we fall back on an alternate
1929 implementation method. */
1930 #define NUM_UNITOP_CUTOFF 20
1932 if (num_unit_opclasses
< NUM_UNITOP_CUTOFF
)
1934 /* Merge each function unit into the unit mask attributes. */
1935 for (unit
= units
; unit
; unit
= unit
->next
)
1937 XEXP (newexp
, 0) = unit
->condexp
;
1938 XEXP (newexp
, 1) = make_numeric_value (1 << unit
->num
);
1939 unitsmask
= operate_exp (OR_OP
, unitsmask
, newexp
);
1944 /* Merge each function unit into the unit mask attributes. */
1945 for (unit
= units
; unit
; unit
= unit
->next
)
1947 XEXP (newexp
, 0) = unit
->condexp
;
1948 XEXP (newexp
, 1) = make_numeric_value (1 << unit
->num
);
1949 unitsmask
= operate_exp (ORX_OP
, unitsmask
, attr_copy_rtx (newexp
));
1953 /* Simplify the unit mask expression, encode it, and make an attribute
1954 for the function_units_used function. */
1955 unitsmask
= simplify_by_exploding (unitsmask
);
1957 if (num_unit_opclasses
< NUM_UNITOP_CUTOFF
)
1958 unitsmask
= encode_units_mask (unitsmask
);
1961 /* We can no longer encode unitsmask at compile time, so emit code to
1962 calculate it at runtime. Rather, put a marker for where we'd do
1963 the code, and actually output it in write_attr_get(). */
1964 unitsmask
= attr_rtx (FFS
, unitsmask
);
1967 make_internal_attr ("*function_units_used", unitsmask
, 10);
1969 /* Create an array of ops for each unit. Add an extra unit for the
1970 result_ready_cost function that has the ops of all other units. */
1971 unit_ops
= (struct function_unit_op
***)
1972 xmalloc ((num_units
+ 1) * sizeof (struct function_unit_op
**));
1973 unit_num
= (struct function_unit
**)
1974 xmalloc ((num_units
+ 1) * sizeof (struct function_unit
*));
1976 unit_num
[num_units
] = unit
= (struct function_unit
*)
1977 xmalloc (sizeof (struct function_unit
));
1978 unit
->num
= num_units
;
1979 unit
->num_opclasses
= 0;
1981 for (unit
= units
; unit
; unit
= unit
->next
)
1983 unit_num
[num_units
]->num_opclasses
+= unit
->num_opclasses
;
1984 unit_num
[unit
->num
] = unit
;
1985 unit_ops
[unit
->num
] = op_array
= (struct function_unit_op
**)
1986 xmalloc (unit
->num_opclasses
* sizeof (struct function_unit_op
*));
1988 for (op
= unit
->ops
; op
; op
= op
->next
)
1989 op_array
[op
->num
] = op
;
1992 /* Compose the array of ops for the extra unit. */
1993 unit_ops
[num_units
] = op_array
= (struct function_unit_op
**)
1994 xmalloc (unit_num
[num_units
]->num_opclasses
1995 * sizeof (struct function_unit_op
*));
1997 for (unit
= units
, i
= 0; unit
; i
+= unit
->num_opclasses
, unit
= unit
->next
)
1998 memcpy (&op_array
[i
], unit_ops
[unit
->num
],
1999 unit
->num_opclasses
* sizeof (struct function_unit_op
*));
2001 /* Compute the ready cost function for each unit by computing the
2002 condition for each non-default value. */
2003 for (u
= 0; u
<= num_units
; u
++)
2009 op_array
= unit_ops
[unit
->num
];
2010 num
= unit
->num_opclasses
;
2012 /* Sort the array of ops into increasing ready cost order. */
2013 for (i
= 0; i
< num
; i
++)
2014 for (j
= num
- 1; j
> i
; j
--)
2015 if (op_array
[j
- 1]->ready
< op_array
[j
]->ready
)
2018 op_array
[j
] = op_array
[j
- 1];
2019 op_array
[j
- 1] = op
;
2022 /* Determine how many distinct non-default ready cost values there
2023 are. We use a default ready cost value of 1. */
2024 nvalues
= 0; value
= 1;
2025 for (i
= num
- 1; i
>= 0; i
--)
2026 if (op_array
[i
]->ready
> value
)
2028 value
= op_array
[i
]->ready
;
2033 readycost
= make_numeric_value (1);
2036 /* Construct the ready cost expression as a COND of each value from
2037 the largest to the smallest. */
2038 readycost
= rtx_alloc (COND
);
2039 XVEC (readycost
, 0) = rtvec_alloc (nvalues
* 2);
2040 XEXP (readycost
, 1) = make_numeric_value (1);
2044 value
= op_array
[0]->ready
;
2045 for (i
= 0; i
< num
; i
++)
2050 else if (op
->ready
== value
)
2051 orexp
= insert_right_side (IOR
, orexp
, op
->condexp
, -2, -2);
2054 XVECEXP (readycost
, 0, nvalues
* 2) = orexp
;
2055 XVECEXP (readycost
, 0, nvalues
* 2 + 1)
2056 = make_numeric_value (value
);
2059 orexp
= op
->condexp
;
2062 XVECEXP (readycost
, 0, nvalues
* 2) = orexp
;
2063 XVECEXP (readycost
, 0, nvalues
* 2 + 1) = make_numeric_value (value
);
2068 rtx max_blockage
= 0, min_blockage
= 0;
2070 /* Simplify the readycost expression by only considering insns
2071 that use the unit. */
2072 readycost
= simplify_knowing (readycost
, unit
->condexp
);
2074 /* Determine the blockage cost the executing insn (E) given
2075 the candidate insn (C). This is the maximum of the issue
2076 delay, the pipeline delay, and the simultaneity constraint.
2077 Each function_unit_op represents the characteristics of the
2078 candidate insn, so in the expressions below, C is a known
2079 term and E is an unknown term.
2081 We compute the blockage cost for each E for every possible C.
2082 Thus OP represents E, and READYCOST is a list of values for
2085 The issue delay function for C is op->issue_exp and is used to
2086 write the `<name>_unit_conflict_cost' function. Symbolicly
2087 this is "ISSUE-DELAY (E,C)".
2089 The pipeline delay results form the FIFO constraint on the
2090 function unit and is "READY-COST (E) + 1 - READY-COST (C)".
2092 The simultaneity constraint is based on how long it takes to
2093 fill the unit given the minimum issue delay. FILL-TIME is the
2094 constant "MIN (ISSUE-DELAY (*,*)) * (SIMULTANEITY - 1)", and
2095 the simultaneity constraint is "READY-COST (E) - FILL-TIME"
2096 if SIMULTANEITY is non-zero and zero otherwise.
2098 Thus, BLOCKAGE (E,C) when SIMULTANEITY is zero is
2100 MAX (ISSUE-DELAY (E,C),
2101 READY-COST (E) - (READY-COST (C) - 1))
2105 MAX (ISSUE-DELAY (E,C),
2106 READY-COST (E) - (READY-COST (C) - 1),
2107 READY-COST (E) - FILL-TIME)
2109 The `<name>_unit_blockage' function is computed by determining
2110 this value for each candidate insn. As these values are
2111 computed, we also compute the upper and lower bounds for
2112 BLOCKAGE (E,*). These are combined to form the function
2113 `<name>_unit_blockage_range'. Finally, the maximum blockage
2114 cost, MAX (BLOCKAGE (*,*)), is computed. */
2116 for (op
= unit
->ops
; op
; op
= op
->next
)
2118 rtx blockage
= op
->issue_exp
;
2119 blockage
= simplify_knowing (blockage
, unit
->condexp
);
2121 /* Add this op's contribution to MAX (BLOCKAGE (E,*)) and
2122 MIN (BLOCKAGE (E,*)). */
2123 if (max_blockage
== 0)
2124 max_blockage
= min_blockage
= blockage
;
2128 = simplify_knowing (operate_exp (MAX_OP
, max_blockage
,
2132 = simplify_knowing (operate_exp (MIN_OP
, min_blockage
,
2137 /* Make an attribute for use in the blockage function. */
2138 str
= attr_printf ((strlen (unit
->name
) + sizeof "*_block_"
2140 "*%s_block_%d", unit
->name
, op
->num
);
2141 make_internal_attr (str
, blockage
, 1);
2144 /* Record MAX (BLOCKAGE (*,*)). */
2147 unit
->max_blockage
= max_attr_value (max_blockage
, &unknown
);
2150 /* See if the upper and lower bounds of BLOCKAGE (E,*) are the
2151 same. If so, the blockage function carries no additional
2152 information and is not written. */
2153 newexp
= operate_exp (EQ_OP
, max_blockage
, min_blockage
);
2154 newexp
= simplify_knowing (newexp
, unit
->condexp
);
2155 unit
->needs_blockage_function
2156 = (GET_CODE (newexp
) != CONST_STRING
2157 || atoi (XSTR (newexp
, 0)) != 1);
2159 /* If the all values of BLOCKAGE (E,C) have the same value,
2160 neither blockage function is written. */
2161 unit
->needs_range_function
2162 = (unit
->needs_blockage_function
2163 || GET_CODE (max_blockage
) != CONST_STRING
);
2165 if (unit
->needs_range_function
)
2167 /* Compute the blockage range function and make an attribute
2168 for writing its value. */
2169 newexp
= operate_exp (RANGE_OP
, min_blockage
, max_blockage
);
2170 newexp
= simplify_knowing (newexp
, unit
->condexp
);
2172 str
= attr_printf ((strlen (unit
->name
)
2173 + sizeof "*_unit_blockage_range"),
2174 "*%s_unit_blockage_range", unit
->name
);
2175 make_internal_attr (str
, newexp
, 20);
2178 str
= attr_printf (strlen (unit
->name
) + sizeof "*_unit_ready_cost",
2179 "*%s_unit_ready_cost", unit
->name
);
2182 str
= "*result_ready_cost";
2184 /* Make an attribute for the ready_cost function. Simplifying
2185 further with simplify_by_exploding doesn't win. */
2186 make_internal_attr (str
, readycost
, 0);
2189 /* For each unit that requires a conflict cost function, make an attribute
2190 that maps insns to the operation number. */
2191 for (unit
= units
; unit
; unit
= unit
->next
)
2195 if (! unit
->needs_conflict_function
2196 && ! unit
->needs_blockage_function
)
2199 caseexp
= rtx_alloc (COND
);
2200 XVEC (caseexp
, 0) = rtvec_alloc ((unit
->num_opclasses
- 1) * 2);
2202 for (op
= unit
->ops
; op
; op
= op
->next
)
2204 /* Make our adjustment to the COND being computed. If we are the
2205 last operation class, place our values into the default of the
2207 if (op
->num
== unit
->num_opclasses
- 1)
2209 XEXP (caseexp
, 1) = make_numeric_value (op
->num
);
2213 XVECEXP (caseexp
, 0, op
->num
* 2) = op
->condexp
;
2214 XVECEXP (caseexp
, 0, op
->num
* 2 + 1)
2215 = make_numeric_value (op
->num
);
2219 /* Simplifying caseexp with simplify_by_exploding doesn't win. */
2220 str
= attr_printf (strlen (unit
->name
) + sizeof "*_cases",
2221 "*%s_cases", unit
->name
);
2222 make_internal_attr (str
, caseexp
, 1);
2226 /* Simplify EXP given KNOWN_TRUE. */
2229 simplify_knowing (exp
, known_true
)
2230 rtx exp
, known_true
;
2232 if (GET_CODE (exp
) != CONST_STRING
)
2234 int unknown
= 0, max
;
2235 max
= max_attr_value (exp
, &unknown
);
2238 exp
= attr_rtx (IF_THEN_ELSE
, known_true
, exp
,
2239 make_numeric_value (max
));
2240 exp
= simplify_by_exploding (exp
);
2246 /* Translate the CONST_STRING expressions in X to change the encoding of
2247 value. On input, the value is a bitmask with a one bit for each unit
2248 used; on output, the value is the unit number (zero based) if one
2249 and only one unit is used or the one's compliment of the bitmask. */
2252 encode_units_mask (x
)
2260 code
= GET_CODE (x
);
2265 i
= atoi (XSTR (x
, 0));
2267 /* The sign bit encodes a one's compliment mask. */
2269 else if (i
!= 0 && i
== (i
& -i
))
2270 /* Only one bit is set, so yield that unit number. */
2271 for (j
= 0; (i
>>= 1) != 0; j
++)
2275 return attr_rtx (CONST_STRING
, attr_printf (MAX_DIGITS
, "%d", j
));
2292 /* Compare the elements. If any pair of corresponding elements
2293 fail to match, return 0 for the whole things. */
2295 fmt
= GET_RTX_FORMAT (code
);
2296 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
2302 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
2303 XVECEXP (x
, i
, j
) = encode_units_mask (XVECEXP (x
, i
, j
));
2307 XEXP (x
, i
) = encode_units_mask (XEXP (x
, i
));
2314 /* Once all attributes and insns have been read and checked, we construct for
2315 each attribute value a list of all the insns that have that value for
2320 struct attr_desc
*attr
;
2322 struct attr_value
*av
;
2323 struct insn_ent
*ie
;
2324 struct insn_def
*id
;
2328 /* Don't fill constant attributes. The value is independent of
2329 any particular insn. */
2333 for (id
= defs
; id
; id
= id
->next
)
2335 /* If no value is specified for this insn for this attribute, use the
2338 if (XVEC (id
->def
, id
->vec_idx
))
2339 for (i
= 0; i
< XVECLEN (id
->def
, id
->vec_idx
); i
++)
2340 if (! strcmp (XSTR (XEXP (XVECEXP (id
->def
, id
->vec_idx
, i
), 0), 0),
2342 value
= XEXP (XVECEXP (id
->def
, id
->vec_idx
, i
), 1);
2345 av
= attr
->default_val
;
2347 av
= get_attr_value (value
, attr
, id
->insn_code
);
2349 ie
= (struct insn_ent
*) oballoc (sizeof (struct insn_ent
));
2350 ie
->insn_code
= id
->insn_code
;
2351 ie
->insn_index
= id
->insn_code
;
2352 insert_insn_ent (av
, ie
);
2356 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
2357 test that checks relative positions of insns (uses MATCH_DUP or PC).
2358 If so, replace it with what is obtained by passing the expression to
2359 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
2360 recursively on each value (including the default value). Otherwise,
2361 return the value returned by NO_ADDRESS_FN applied to EXP. */
2364 substitute_address (exp
, no_address_fn
, address_fn
)
2366 rtx (*no_address_fn
) PARAMS ((rtx
));
2367 rtx (*address_fn
) PARAMS ((rtx
));
2372 if (GET_CODE (exp
) == COND
)
2374 /* See if any tests use addresses. */
2376 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
2377 walk_attr_value (XVECEXP (exp
, 0, i
));
2380 return (*address_fn
) (exp
);
2382 /* Make a new copy of this COND, replacing each element. */
2383 newexp
= rtx_alloc (COND
);
2384 XVEC (newexp
, 0) = rtvec_alloc (XVECLEN (exp
, 0));
2385 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
2387 XVECEXP (newexp
, 0, i
) = XVECEXP (exp
, 0, i
);
2388 XVECEXP (newexp
, 0, i
+ 1)
2389 = substitute_address (XVECEXP (exp
, 0, i
+ 1),
2390 no_address_fn
, address_fn
);
2393 XEXP (newexp
, 1) = substitute_address (XEXP (exp
, 1),
2394 no_address_fn
, address_fn
);
2399 else if (GET_CODE (exp
) == IF_THEN_ELSE
)
2402 walk_attr_value (XEXP (exp
, 0));
2404 return (*address_fn
) (exp
);
2406 return attr_rtx (IF_THEN_ELSE
,
2407 substitute_address (XEXP (exp
, 0),
2408 no_address_fn
, address_fn
),
2409 substitute_address (XEXP (exp
, 1),
2410 no_address_fn
, address_fn
),
2411 substitute_address (XEXP (exp
, 2),
2412 no_address_fn
, address_fn
));
2415 return (*no_address_fn
) (exp
);
2418 /* Make new attributes from the `length' attribute. The following are made,
2419 each corresponding to a function called from `shorten_branches' or
2422 *insn_default_length This is the length of the insn to be returned
2423 by `get_attr_length' before `shorten_branches'
2424 has been called. In each case where the length
2425 depends on relative addresses, the largest
2426 possible is used. This routine is also used
2427 to compute the initial size of the insn.
2429 *insn_variable_length_p This returns 1 if the insn's length depends
2430 on relative addresses, zero otherwise.
2432 *insn_current_length This is only called when it is known that the
2433 insn has a variable length and returns the
2434 current length, based on relative addresses.
2438 make_length_attrs ()
2440 static const char *const new_names
[] = {"*insn_default_length",
2441 "*insn_variable_length_p",
2442 "*insn_current_length"};
2443 static rtx (*const no_address_fn
[]) PARAMS ((rtx
)) = {identity_fn
, zero_fn
, zero_fn
};
2444 static rtx (*const address_fn
[]) PARAMS ((rtx
)) = {max_fn
, one_fn
, identity_fn
};
2446 struct attr_desc
*length_attr
, *new_attr
;
2447 struct attr_value
*av
, *new_av
;
2448 struct insn_ent
*ie
, *new_ie
;
2450 /* See if length attribute is defined. If so, it must be numeric. Make
2451 it special so we don't output anything for it. */
2452 length_attr
= find_attr ("length", 0);
2453 if (length_attr
== 0)
2456 if (! length_attr
->is_numeric
)
2457 fatal ("length attribute must be numeric");
2459 length_attr
->is_const
= 0;
2460 length_attr
->is_special
= 1;
2462 /* Make each new attribute, in turn. */
2463 for (i
= 0; i
< ARRAY_SIZE (new_names
); i
++)
2465 make_internal_attr (new_names
[i
],
2466 substitute_address (length_attr
->default_val
->value
,
2467 no_address_fn
[i
], address_fn
[i
]),
2469 new_attr
= find_attr (new_names
[i
], 0);
2470 for (av
= length_attr
->first_value
; av
; av
= av
->next
)
2471 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2473 new_av
= get_attr_value (substitute_address (av
->value
,
2476 new_attr
, ie
->insn_code
);
2477 new_ie
= (struct insn_ent
*) oballoc (sizeof (struct insn_ent
));
2478 new_ie
->insn_code
= ie
->insn_code
;
2479 new_ie
->insn_index
= ie
->insn_index
;
2480 insert_insn_ent (new_av
, new_ie
);
2485 /* Utility functions called from above routine. */
2496 rtx exp ATTRIBUTE_UNUSED
;
2498 return make_numeric_value (0);
2503 rtx exp ATTRIBUTE_UNUSED
;
2505 return make_numeric_value (1);
2513 return make_numeric_value (max_attr_value (exp
, &unknown
));
2517 write_length_unit_log ()
2519 struct attr_desc
*length_attr
= find_attr ("length", 0);
2520 struct attr_value
*av
;
2521 struct insn_ent
*ie
;
2522 unsigned int length_unit_log
, length_or
;
2525 if (length_attr
== 0)
2527 length_or
= or_attr_value (length_attr
->default_val
->value
, &unknown
);
2528 for (av
= length_attr
->first_value
; av
; av
= av
->next
)
2529 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2530 length_or
|= or_attr_value (av
->value
, &unknown
);
2533 length_unit_log
= 0;
2536 length_or
= ~length_or
;
2537 for (length_unit_log
= 0; length_or
& 1; length_or
>>= 1)
2540 printf ("int length_unit_log = %u;\n", length_unit_log
);
2543 /* Take a COND expression and see if any of the conditions in it can be
2544 simplified. If any are known true or known false for the particular insn
2545 code, the COND can be further simplified.
2547 Also call ourselves on any COND operations that are values of this COND.
2549 We do not modify EXP; rather, we make and return a new rtx. */
2552 simplify_cond (exp
, insn_code
, insn_index
)
2554 int insn_code
, insn_index
;
2557 /* We store the desired contents here,
2558 then build a new expression if they don't match EXP. */
2559 rtx defval
= XEXP (exp
, 1);
2560 rtx new_defval
= XEXP (exp
, 1);
2561 int len
= XVECLEN (exp
, 0);
2562 rtx
*tests
= (rtx
*) xmalloc (len
* sizeof (rtx
));
2567 /* This lets us free all storage allocated below, if appropriate. */
2568 first_spacer
= (char *) obstack_finish (rtl_obstack
);
2570 memcpy (tests
, XVEC (exp
, 0)->elem
, len
* sizeof (rtx
));
2572 /* See if default value needs simplification. */
2573 if (GET_CODE (defval
) == COND
)
2574 new_defval
= simplify_cond (defval
, insn_code
, insn_index
);
2576 /* Simplify the subexpressions, and see what tests we can get rid of. */
2578 for (i
= 0; i
< len
; i
+= 2)
2580 rtx newtest
, newval
;
2582 /* Simplify this test. */
2583 newtest
= simplify_test_exp_in_temp (tests
[i
], insn_code
, insn_index
);
2586 newval
= tests
[i
+ 1];
2587 /* See if this value may need simplification. */
2588 if (GET_CODE (newval
) == COND
)
2589 newval
= simplify_cond (newval
, insn_code
, insn_index
);
2591 /* Look for ways to delete or combine this test. */
2592 if (newtest
== true_rtx
)
2594 /* If test is true, make this value the default
2595 and discard this + any following tests. */
2597 defval
= tests
[i
+ 1];
2598 new_defval
= newval
;
2601 else if (newtest
== false_rtx
)
2603 /* If test is false, discard it and its value. */
2604 for (j
= i
; j
< len
- 2; j
++)
2605 tests
[j
] = tests
[j
+ 2];
2609 else if (i
> 0 && attr_equal_p (newval
, tests
[i
- 1]))
2611 /* If this value and the value for the prev test are the same,
2615 = insert_right_side (IOR
, tests
[i
- 2], newtest
,
2616 insn_code
, insn_index
);
2618 /* Delete this test/value. */
2619 for (j
= i
; j
< len
- 2; j
++)
2620 tests
[j
] = tests
[j
+ 2];
2625 tests
[i
+ 1] = newval
;
2628 /* If the last test in a COND has the same value
2629 as the default value, that test isn't needed. */
2631 while (len
> 0 && attr_equal_p (tests
[len
- 1], new_defval
))
2634 /* See if we changed anything. */
2635 if (len
!= XVECLEN (exp
, 0) || new_defval
!= XEXP (exp
, 1))
2638 for (i
= 0; i
< len
; i
++)
2639 if (! attr_equal_p (tests
[i
], XVECEXP (exp
, 0, i
)))
2647 if (GET_CODE (defval
) == COND
)
2648 ret
= simplify_cond (defval
, insn_code
, insn_index
);
2656 rtx newexp
= rtx_alloc (COND
);
2658 XVEC (newexp
, 0) = rtvec_alloc (len
);
2659 memcpy (XVEC (newexp
, 0)->elem
, tests
, len
* sizeof (rtx
));
2660 XEXP (newexp
, 1) = new_defval
;
2667 /* Remove an insn entry from an attribute value. */
2670 remove_insn_ent (av
, ie
)
2671 struct attr_value
*av
;
2672 struct insn_ent
*ie
;
2674 struct insn_ent
*previe
;
2676 if (av
->first_insn
== ie
)
2677 av
->first_insn
= ie
->next
;
2680 for (previe
= av
->first_insn
; previe
->next
!= ie
; previe
= previe
->next
)
2682 previe
->next
= ie
->next
;
2686 if (ie
->insn_code
== -1)
2687 av
->has_asm_insn
= 0;
2692 /* Insert an insn entry in an attribute value list. */
2695 insert_insn_ent (av
, ie
)
2696 struct attr_value
*av
;
2697 struct insn_ent
*ie
;
2699 ie
->next
= av
->first_insn
;
2700 av
->first_insn
= ie
;
2702 if (ie
->insn_code
== -1)
2703 av
->has_asm_insn
= 1;
2708 /* This is a utility routine to take an expression that is a tree of either
2709 AND or IOR expressions and insert a new term. The new term will be
2710 inserted at the right side of the first node whose code does not match
2711 the root. A new node will be created with the root's code. Its left
2712 side will be the old right side and its right side will be the new
2715 If the `term' is itself a tree, all its leaves will be inserted. */
2718 insert_right_side (code
, exp
, term
, insn_code
, insn_index
)
2722 int insn_code
, insn_index
;
2726 /* Avoid consing in some special cases. */
2727 if (code
== AND
&& term
== true_rtx
)
2729 if (code
== AND
&& term
== false_rtx
)
2731 if (code
== AND
&& exp
== true_rtx
)
2733 if (code
== AND
&& exp
== false_rtx
)
2735 if (code
== IOR
&& term
== true_rtx
)
2737 if (code
== IOR
&& term
== false_rtx
)
2739 if (code
== IOR
&& exp
== true_rtx
)
2741 if (code
== IOR
&& exp
== false_rtx
)
2743 if (attr_equal_p (exp
, term
))
2746 if (GET_CODE (term
) == code
)
2748 exp
= insert_right_side (code
, exp
, XEXP (term
, 0),
2749 insn_code
, insn_index
);
2750 exp
= insert_right_side (code
, exp
, XEXP (term
, 1),
2751 insn_code
, insn_index
);
2756 if (GET_CODE (exp
) == code
)
2758 rtx
new = insert_right_side (code
, XEXP (exp
, 1),
2759 term
, insn_code
, insn_index
);
2760 if (new != XEXP (exp
, 1))
2761 /* Make a copy of this expression and call recursively. */
2762 newexp
= attr_rtx (code
, XEXP (exp
, 0), new);
2768 /* Insert the new term. */
2769 newexp
= attr_rtx (code
, exp
, term
);
2772 return simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2775 /* If we have an expression which AND's a bunch of
2776 (not (eq_attrq "alternative" "n"))
2777 terms, we may have covered all or all but one of the possible alternatives.
2778 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
2780 This routine is passed an expression and either AND or IOR. It returns a
2781 bitmask indicating which alternatives are mentioned within EXP. */
2784 compute_alternative_mask (exp
, code
)
2789 if (GET_CODE (exp
) == code
)
2790 return compute_alternative_mask (XEXP (exp
, 0), code
)
2791 | compute_alternative_mask (XEXP (exp
, 1), code
);
2793 else if (code
== AND
&& GET_CODE (exp
) == NOT
2794 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
2795 && XSTR (XEXP (exp
, 0), 0) == alternative_name
)
2796 string
= XSTR (XEXP (exp
, 0), 1);
2798 else if (code
== IOR
&& GET_CODE (exp
) == EQ_ATTR
2799 && XSTR (exp
, 0) == alternative_name
)
2800 string
= XSTR (exp
, 1);
2806 return 1 << (string
[0] - '0');
2807 return 1 << atoi (string
);
2810 /* Given I, a single-bit mask, return RTX to compare the `alternative'
2811 attribute with the value represented by that bit. */
2814 make_alternative_compare (mask
)
2821 for (i
= 0; (mask
& (1 << i
)) == 0; i
++)
2824 newexp
= attr_rtx (EQ_ATTR
, alternative_name
, attr_numeral (i
));
2825 RTX_UNCHANGING_P (newexp
) = 1;
2830 /* If we are processing an (eq_attr "attr" "value") test, we find the value
2831 of "attr" for this insn code. From that value, we can compute a test
2832 showing when the EQ_ATTR will be true. This routine performs that
2833 computation. If a test condition involves an address, we leave the EQ_ATTR
2834 intact because addresses are only valid for the `length' attribute.
2836 EXP is the EQ_ATTR expression and VALUE is the value of that attribute
2837 for the insn corresponding to INSN_CODE and INSN_INDEX. */
2840 evaluate_eq_attr (exp
, value
, insn_code
, insn_index
)
2843 int insn_code
, insn_index
;
2850 if (GET_CODE (value
) == CONST_STRING
)
2852 if (! strcmp (XSTR (value
, 0), XSTR (exp
, 1)))
2857 else if (GET_CODE (value
) == SYMBOL_REF
)
2862 if (GET_CODE (exp
) != EQ_ATTR
)
2865 if (strlen (XSTR (exp
, 0)) + strlen (XSTR (exp
, 1)) + 2 > 256)
2868 strcpy (string
, XSTR (exp
, 0));
2869 strcat (string
, "_");
2870 strcat (string
, XSTR (exp
, 1));
2871 for (p
= string
; *p
; p
++)
2874 newexp
= attr_rtx (EQ
, value
,
2875 attr_rtx (SYMBOL_REF
,
2876 attr_string (string
, strlen (string
))));
2878 else if (GET_CODE (value
) == COND
)
2880 /* We construct an IOR of all the cases for which the requested attribute
2881 value is present. Since we start with FALSE, if it is not present,
2882 FALSE will be returned.
2884 Each case is the AND of the NOT's of the previous conditions with the
2885 current condition; in the default case the current condition is TRUE.
2887 For each possible COND value, call ourselves recursively.
2889 The extra TRUE and FALSE expressions will be eliminated by another
2890 call to the simplification routine. */
2895 if (current_alternative_string
)
2896 clear_struct_flag (value
);
2898 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
2900 rtx
this = simplify_test_exp_in_temp (XVECEXP (value
, 0, i
),
2901 insn_code
, insn_index
);
2903 SIMPLIFY_ALTERNATIVE (this);
2905 right
= insert_right_side (AND
, andexp
, this,
2906 insn_code
, insn_index
);
2907 right
= insert_right_side (AND
, right
,
2908 evaluate_eq_attr (exp
,
2911 insn_code
, insn_index
),
2912 insn_code
, insn_index
);
2913 orexp
= insert_right_side (IOR
, orexp
, right
,
2914 insn_code
, insn_index
);
2916 /* Add this condition into the AND expression. */
2917 newexp
= attr_rtx (NOT
, this);
2918 andexp
= insert_right_side (AND
, andexp
, newexp
,
2919 insn_code
, insn_index
);
2922 /* Handle the default case. */
2923 right
= insert_right_side (AND
, andexp
,
2924 evaluate_eq_attr (exp
, XEXP (value
, 1),
2925 insn_code
, insn_index
),
2926 insn_code
, insn_index
);
2927 newexp
= insert_right_side (IOR
, orexp
, right
, insn_code
, insn_index
);
2932 /* If uses an address, must return original expression. But set the
2933 RTX_UNCHANGING_P bit so we don't try to simplify it again. */
2936 walk_attr_value (newexp
);
2940 /* This had `&& current_alternative_string', which seems to be wrong. */
2941 if (! RTX_UNCHANGING_P (exp
))
2942 return copy_rtx_unchanging (exp
);
2949 /* This routine is called when an AND of a term with a tree of AND's is
2950 encountered. If the term or its complement is present in the tree, it
2951 can be replaced with TRUE or FALSE, respectively.
2953 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2954 be true and hence are complementary.
2956 There is one special case: If we see
2957 (and (not (eq_attr "att" "v1"))
2958 (eq_attr "att" "v2"))
2959 this can be replaced by (eq_attr "att" "v2"). To do this we need to
2960 replace the term, not anything in the AND tree. So we pass a pointer to
2964 simplify_and_tree (exp
, pterm
, insn_code
, insn_index
)
2967 int insn_code
, insn_index
;
2972 int left_eliminates_term
, right_eliminates_term
;
2974 if (GET_CODE (exp
) == AND
)
2976 left
= simplify_and_tree (XEXP (exp
, 0), pterm
, insn_code
, insn_index
);
2977 right
= simplify_and_tree (XEXP (exp
, 1), pterm
, insn_code
, insn_index
);
2978 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2980 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
2982 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2986 else if (GET_CODE (exp
) == IOR
)
2988 /* For the IOR case, we do the same as above, except that we can
2989 only eliminate `term' if both sides of the IOR would do so. */
2991 left
= simplify_and_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
2992 left_eliminates_term
= (temp
== true_rtx
);
2995 right
= simplify_and_tree (XEXP (exp
, 1), &temp
, insn_code
, insn_index
);
2996 right_eliminates_term
= (temp
== true_rtx
);
2998 if (left_eliminates_term
&& right_eliminates_term
)
3001 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
3003 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
3005 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
3009 /* Check for simplifications. Do some extra checking here since this
3010 routine is called so many times. */
3015 else if (GET_CODE (exp
) == NOT
&& XEXP (exp
, 0) == *pterm
)
3018 else if (GET_CODE (*pterm
) == NOT
&& exp
== XEXP (*pterm
, 0))
3021 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == EQ_ATTR
)
3023 if (XSTR (exp
, 0) != XSTR (*pterm
, 0))
3026 if (! strcmp (XSTR (exp
, 1), XSTR (*pterm
, 1)))
3032 else if (GET_CODE (*pterm
) == EQ_ATTR
&& GET_CODE (exp
) == NOT
3033 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
)
3035 if (XSTR (*pterm
, 0) != XSTR (XEXP (exp
, 0), 0))
3038 if (! strcmp (XSTR (*pterm
, 1), XSTR (XEXP (exp
, 0), 1)))
3044 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == NOT
3045 && GET_CODE (XEXP (*pterm
, 0)) == EQ_ATTR
)
3047 if (XSTR (exp
, 0) != XSTR (XEXP (*pterm
, 0), 0))
3050 if (! strcmp (XSTR (exp
, 1), XSTR (XEXP (*pterm
, 0), 1)))
3056 else if (GET_CODE (exp
) == NOT
&& GET_CODE (*pterm
) == NOT
)
3058 if (attr_equal_p (XEXP (exp
, 0), XEXP (*pterm
, 0)))
3062 else if (GET_CODE (exp
) == NOT
)
3064 if (attr_equal_p (XEXP (exp
, 0), *pterm
))
3068 else if (GET_CODE (*pterm
) == NOT
)
3070 if (attr_equal_p (XEXP (*pterm
, 0), exp
))
3074 else if (attr_equal_p (exp
, *pterm
))
3080 /* Similar to `simplify_and_tree', but for IOR trees. */
3083 simplify_or_tree (exp
, pterm
, insn_code
, insn_index
)
3086 int insn_code
, insn_index
;
3091 int left_eliminates_term
, right_eliminates_term
;
3093 if (GET_CODE (exp
) == IOR
)
3095 left
= simplify_or_tree (XEXP (exp
, 0), pterm
, insn_code
, insn_index
);
3096 right
= simplify_or_tree (XEXP (exp
, 1), pterm
, insn_code
, insn_index
);
3097 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
3099 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
3101 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
3105 else if (GET_CODE (exp
) == AND
)
3107 /* For the AND case, we do the same as above, except that we can
3108 only eliminate `term' if both sides of the AND would do so. */
3110 left
= simplify_or_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
3111 left_eliminates_term
= (temp
== false_rtx
);
3114 right
= simplify_or_tree (XEXP (exp
, 1), &temp
, insn_code
, insn_index
);
3115 right_eliminates_term
= (temp
== false_rtx
);
3117 if (left_eliminates_term
&& right_eliminates_term
)
3120 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
3122 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
3124 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
3128 if (attr_equal_p (exp
, *pterm
))
3131 else if (GET_CODE (exp
) == NOT
&& attr_equal_p (XEXP (exp
, 0), *pterm
))
3134 else if (GET_CODE (*pterm
) == NOT
&& attr_equal_p (XEXP (*pterm
, 0), exp
))
3137 else if (GET_CODE (*pterm
) == EQ_ATTR
&& GET_CODE (exp
) == NOT
3138 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
3139 && XSTR (*pterm
, 0) == XSTR (XEXP (exp
, 0), 0))
3142 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == NOT
3143 && GET_CODE (XEXP (*pterm
, 0)) == EQ_ATTR
3144 && XSTR (exp
, 0) == XSTR (XEXP (*pterm
, 0), 0))
3149 /* Compute approximate cost of the expression. Used to decide whether
3150 expression is cheap enough for inline. */
3159 code
= GET_CODE (x
);
3168 /* Alternatives don't result into function call. */
3169 if (!strcmp (XSTR (x
, 0), "alternative"))
3176 const char *fmt
= GET_RTX_FORMAT (code
);
3177 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
3183 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
3184 cost
+= attr_rtx_cost (XVECEXP (x
, i
, j
));
3187 cost
+= attr_rtx_cost (XEXP (x
, i
));
3198 /* Simplify test expression and use temporary obstack in order to avoid
3199 memory bloat. Use RTX_UNCHANGING_P to avoid unnecesary simplifications
3200 and avoid unnecesary copying if possible. */
3203 simplify_test_exp_in_temp (exp
, insn_code
, insn_index
)
3205 int insn_code
, insn_index
;
3208 struct obstack
*old
;
3209 if (RTX_UNCHANGING_P (exp
))
3212 rtl_obstack
= temp_obstack
;
3213 x
= simplify_test_exp (exp
, insn_code
, insn_index
);
3215 if (x
== exp
|| rtl_obstack
== temp_obstack
)
3217 return attr_copy_rtx (x
);
3220 /* Given an expression, see if it can be simplified for a particular insn
3221 code based on the values of other attributes being tested. This can
3222 eliminate nested get_attr_... calls.
3224 Note that if an endless recursion is specified in the patterns, the
3225 optimization will loop. However, it will do so in precisely the cases where
3226 an infinite recursion loop could occur during compilation. It's better that
3230 simplify_test_exp (exp
, insn_code
, insn_index
)
3232 int insn_code
, insn_index
;
3235 struct attr_desc
*attr
;
3236 struct attr_value
*av
;
3237 struct insn_ent
*ie
;
3241 /* Don't re-simplify something we already simplified. */
3242 if (RTX_UNCHANGING_P (exp
) || MEM_IN_STRUCT_P (exp
))
3245 switch (GET_CODE (exp
))
3248 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
3249 SIMPLIFY_ALTERNATIVE (left
);
3250 if (left
== false_rtx
)
3252 right
= SIMPLIFY_TEST_EXP (XEXP (exp
, 1), insn_code
, insn_index
);
3253 SIMPLIFY_ALTERNATIVE (right
);
3254 if (left
== false_rtx
)
3257 /* If either side is an IOR and we have (eq_attr "alternative" ..")
3258 present on both sides, apply the distributive law since this will
3259 yield simplifications. */
3260 if ((GET_CODE (left
) == IOR
|| GET_CODE (right
) == IOR
)
3261 && compute_alternative_mask (left
, IOR
)
3262 && compute_alternative_mask (right
, IOR
))
3264 if (GET_CODE (left
) == IOR
)
3271 newexp
= attr_rtx (IOR
,
3272 attr_rtx (AND
, left
, XEXP (right
, 0)),
3273 attr_rtx (AND
, left
, XEXP (right
, 1)));
3275 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
3278 /* Try with the term on both sides. */
3279 right
= simplify_and_tree (right
, &left
, insn_code
, insn_index
);
3280 if (left
== XEXP (exp
, 0) && right
== XEXP (exp
, 1))
3281 left
= simplify_and_tree (left
, &right
, insn_code
, insn_index
);
3283 if (left
== false_rtx
|| right
== false_rtx
)
3285 else if (left
== true_rtx
)
3289 else if (right
== true_rtx
)
3293 /* See if all or all but one of the insn's alternatives are specified
3294 in this tree. Optimize if so. */
3296 else if (insn_code
>= 0
3297 && (GET_CODE (left
) == AND
3298 || (GET_CODE (left
) == NOT
3299 && GET_CODE (XEXP (left
, 0)) == EQ_ATTR
3300 && XSTR (XEXP (left
, 0), 0) == alternative_name
)
3301 || GET_CODE (right
) == AND
3302 || (GET_CODE (right
) == NOT
3303 && GET_CODE (XEXP (right
, 0)) == EQ_ATTR
3304 && XSTR (XEXP (right
, 0), 0) == alternative_name
)))
3306 i
= compute_alternative_mask (exp
, AND
);
3307 if (i
& ~insn_alternatives
[insn_code
])
3308 fatal ("invalid alternative specified for pattern number %d",
3311 /* If all alternatives are excluded, this is false. */
3312 i
^= insn_alternatives
[insn_code
];
3315 else if ((i
& (i
- 1)) == 0 && insn_alternatives
[insn_code
] > 1)
3317 /* If just one excluded, AND a comparison with that one to the
3318 front of the tree. The others will be eliminated by
3319 optimization. We do not want to do this if the insn has one
3320 alternative and we have tested none of them! */
3321 left
= make_alternative_compare (i
);
3322 right
= simplify_and_tree (exp
, &left
, insn_code
, insn_index
);
3323 newexp
= attr_rtx (AND
, left
, right
);
3325 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
3329 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
3331 newexp
= attr_rtx (AND
, left
, right
);
3332 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
3337 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
3338 SIMPLIFY_ALTERNATIVE (left
);
3339 if (left
== true_rtx
)
3341 right
= SIMPLIFY_TEST_EXP (XEXP (exp
, 1), insn_code
, insn_index
);
3342 SIMPLIFY_ALTERNATIVE (right
);
3343 if (right
== true_rtx
)
3346 right
= simplify_or_tree (right
, &left
, insn_code
, insn_index
);
3347 if (left
== XEXP (exp
, 0) && right
== XEXP (exp
, 1))
3348 left
= simplify_or_tree (left
, &right
, insn_code
, insn_index
);
3350 if (right
== true_rtx
|| left
== true_rtx
)
3352 else if (left
== false_rtx
)
3356 else if (right
== false_rtx
)
3361 /* Test for simple cases where the distributive law is useful. I.e.,
3362 convert (ior (and (x) (y))
3368 else if (GET_CODE (left
) == AND
&& GET_CODE (right
) == AND
3369 && attr_equal_p (XEXP (left
, 0), XEXP (right
, 0)))
3371 newexp
= attr_rtx (IOR
, XEXP (left
, 1), XEXP (right
, 1));
3373 left
= XEXP (left
, 0);
3375 newexp
= attr_rtx (AND
, left
, right
);
3376 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
3379 /* See if all or all but one of the insn's alternatives are specified
3380 in this tree. Optimize if so. */
3382 else if (insn_code
>= 0
3383 && (GET_CODE (left
) == IOR
3384 || (GET_CODE (left
) == EQ_ATTR
3385 && XSTR (left
, 0) == alternative_name
)
3386 || GET_CODE (right
) == IOR
3387 || (GET_CODE (right
) == EQ_ATTR
3388 && XSTR (right
, 0) == alternative_name
)))
3390 i
= compute_alternative_mask (exp
, IOR
);
3391 if (i
& ~insn_alternatives
[insn_code
])
3392 fatal ("invalid alternative specified for pattern number %d",
3395 /* If all alternatives are included, this is true. */
3396 i
^= insn_alternatives
[insn_code
];
3399 else if ((i
& (i
- 1)) == 0 && insn_alternatives
[insn_code
] > 1)
3401 /* If just one excluded, IOR a comparison with that one to the
3402 front of the tree. The others will be eliminated by
3403 optimization. We do not want to do this if the insn has one
3404 alternative and we have tested none of them! */
3405 left
= make_alternative_compare (i
);
3406 right
= simplify_and_tree (exp
, &left
, insn_code
, insn_index
);
3407 newexp
= attr_rtx (IOR
, attr_rtx (NOT
, left
), right
);
3409 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
3413 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
3415 newexp
= attr_rtx (IOR
, left
, right
);
3416 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
3421 if (GET_CODE (XEXP (exp
, 0)) == NOT
)
3423 left
= SIMPLIFY_TEST_EXP (XEXP (XEXP (exp
, 0), 0),
3424 insn_code
, insn_index
);
3425 SIMPLIFY_ALTERNATIVE (left
);
3429 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
3430 SIMPLIFY_ALTERNATIVE (left
);
3431 if (GET_CODE (left
) == NOT
)
3432 return XEXP (left
, 0);
3434 if (left
== false_rtx
)
3436 else if (left
== true_rtx
)
3439 /* Try to apply De`Morgan's laws. */
3440 else if (GET_CODE (left
) == IOR
)
3442 newexp
= attr_rtx (AND
,
3443 attr_rtx (NOT
, XEXP (left
, 0)),
3444 attr_rtx (NOT
, XEXP (left
, 1)));
3446 newexp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
3448 else if (GET_CODE (left
) == AND
)
3450 newexp
= attr_rtx (IOR
,
3451 attr_rtx (NOT
, XEXP (left
, 0)),
3452 attr_rtx (NOT
, XEXP (left
, 1)));
3454 newexp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
3456 else if (left
!= XEXP (exp
, 0))
3458 newexp
= attr_rtx (NOT
, left
);
3463 if (current_alternative_string
&& XSTR (exp
, 0) == alternative_name
)
3464 return (XSTR (exp
, 1) == current_alternative_string
3465 ? true_rtx
: false_rtx
);
3467 /* Look at the value for this insn code in the specified attribute.
3468 We normally can replace this comparison with the condition that
3469 would give this insn the values being tested for. */
3470 if (XSTR (exp
, 0) != alternative_name
3471 && (attr
= find_attr (XSTR (exp
, 0), 0)) != NULL
)
3472 for (av
= attr
->first_value
; av
; av
= av
->next
)
3473 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
3474 if (ie
->insn_code
== insn_code
)
3477 x
= evaluate_eq_attr (exp
, av
->value
, insn_code
, insn_index
);
3478 x
= SIMPLIFY_TEST_EXP (x
, insn_code
, insn_index
);
3479 if (attr_rtx_cost(x
) < 20)
3488 /* We have already simplified this expression. Simplifying it again
3489 won't buy anything unless we weren't given a valid insn code
3490 to process (i.e., we are canonicalizing something.). */
3491 if (insn_code
!= -2 /* Seems wrong: && current_alternative_string. */
3492 && ! RTX_UNCHANGING_P (newexp
))
3493 return copy_rtx_unchanging (newexp
);
3498 /* Optimize the attribute lists by seeing if we can determine conditional
3499 values from the known values of other attributes. This will save subroutine
3500 calls during the compilation. */
3505 struct attr_desc
*attr
;
3506 struct attr_value
*av
;
3507 struct insn_ent
*ie
;
3510 struct attr_value_list
3512 struct attr_value
*av
;
3513 struct insn_ent
*ie
;
3514 struct attr_desc
*attr
;
3515 struct attr_value_list
*next
;
3517 struct attr_value_list
**insn_code_values
;
3518 struct attr_value_list
*ivbuf
;
3519 struct attr_value_list
*iv
;
3521 /* For each insn code, make a list of all the insn_ent's for it,
3522 for all values for all attributes. */
3524 if (num_insn_ents
== 0)
3527 /* Make 2 extra elements, for "code" values -2 and -1. */
3529 = (struct attr_value_list
**) xmalloc ((insn_code_number
+ 2)
3530 * sizeof (struct attr_value_list
*));
3531 memset ((char *) insn_code_values
, 0,
3532 (insn_code_number
+ 2) * sizeof (struct attr_value_list
*));
3534 /* Offset the table address so we can index by -2 or -1. */
3535 insn_code_values
+= 2;
3537 iv
= ivbuf
= ((struct attr_value_list
*)
3538 xmalloc (num_insn_ents
* sizeof (struct attr_value_list
)));
3540 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
3541 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
3542 for (av
= attr
->first_value
; av
; av
= av
->next
)
3543 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
3548 iv
->next
= insn_code_values
[ie
->insn_code
];
3549 insn_code_values
[ie
->insn_code
] = iv
;
3553 /* Sanity check on num_insn_ents. */
3554 if (iv
!= ivbuf
+ num_insn_ents
)
3557 /* Process one insn code at a time. */
3558 for (i
= -2; i
< insn_code_number
; i
++)
3560 /* Clear the MEM_IN_STRUCT_P flag everywhere relevant.
3561 We use it to mean "already simplified for this insn". */
3562 for (iv
= insn_code_values
[i
]; iv
; iv
= iv
->next
)
3563 clear_struct_flag (iv
->av
->value
);
3565 for (iv
= insn_code_values
[i
]; iv
; iv
= iv
->next
)
3567 struct obstack
*old
= rtl_obstack
;
3572 if (GET_CODE (av
->value
) != COND
)
3575 rtl_obstack
= temp_obstack
;
3576 #if 0 /* This was intended as a speed up, but it was slower. */
3577 if (insn_n_alternatives
[ie
->insn_code
] > 6
3578 && count_sub_rtxs (av
->value
, 200) >= 200)
3579 newexp
= simplify_by_alternatives (av
->value
, ie
->insn_code
,
3584 while (GET_CODE (newexp
) == COND
)
3586 rtx newexp2
= simplify_cond (newexp
, ie
->insn_code
,
3588 if (newexp2
== newexp
)
3594 if (newexp
!= av
->value
)
3596 newexp
= attr_copy_rtx (newexp
);
3597 remove_insn_ent (av
, ie
);
3598 av
= get_attr_value (newexp
, attr
, ie
->insn_code
);
3600 insert_insn_ent (av
, ie
);
3606 free (insn_code_values
- 2);
3611 simplify_by_alternatives (exp
, insn_code
, insn_index
)
3613 int insn_code
, insn_index
;
3616 int len
= insn_n_alternatives
[insn_code
];
3617 rtx newexp
= rtx_alloc (COND
);
3620 XVEC (newexp
, 0) = rtvec_alloc (len
* 2);
3622 /* It will not matter what value we use as the default value
3623 of the new COND, since that default will never be used.
3624 Choose something of the right type. */
3625 for (ultimate
= exp
; GET_CODE (ultimate
) == COND
;)
3626 ultimate
= XEXP (ultimate
, 1);
3627 XEXP (newexp
, 1) = ultimate
;
3629 for (i
= 0; i
< insn_n_alternatives
[insn_code
]; i
++)
3631 current_alternative_string
= attr_numeral (i
);
3632 XVECEXP (newexp
, 0, i
* 2) = make_alternative_compare (1 << i
);
3633 XVECEXP (newexp
, 0, i
* 2 + 1)
3634 = simplify_cond (exp
, insn_code
, insn_index
);
3637 current_alternative_string
= 0;
3638 return simplify_cond (newexp
, insn_code
, insn_index
);
3642 /* If EXP is a suitable expression, reorganize it by constructing an
3643 equivalent expression that is a COND with the tests being all combinations
3644 of attribute values and the values being simple constants. */
3647 simplify_by_exploding (exp
)
3650 rtx list
= 0, link
, condexp
, defval
= NULL_RTX
;
3651 struct dimension
*space
;
3652 rtx
*condtest
, *condval
;
3653 int i
, j
, total
, ndim
= 0;
3654 int most_tests
, num_marks
, new_marks
;
3657 /* Locate all the EQ_ATTR expressions. */
3658 if (! find_and_mark_used_attributes (exp
, &list
, &ndim
) || ndim
== 0)
3660 unmark_used_attributes (list
, 0, 0);
3664 /* Create an attribute space from the list of used attributes. For each
3665 dimension in the attribute space, record the attribute, list of values
3666 used, and number of values used. Add members to the list of values to
3667 cover the domain of the attribute. This makes the expanded COND form
3668 order independent. */
3670 space
= (struct dimension
*) xmalloc (ndim
* sizeof (struct dimension
));
3673 for (ndim
= 0; list
; ndim
++)
3675 /* Pull the first attribute value from the list and record that
3676 attribute as another dimension in the attribute space. */
3677 const char *name
= XSTR (XEXP (list
, 0), 0);
3680 if ((space
[ndim
].attr
= find_attr (name
, 0)) == 0
3681 || space
[ndim
].attr
->is_numeric
)
3683 unmark_used_attributes (list
, space
, ndim
);
3687 /* Add all remaining attribute values that refer to this attribute. */
3688 space
[ndim
].num_values
= 0;
3689 space
[ndim
].values
= 0;
3691 for (link
= list
; link
; link
= *prev
)
3692 if (! strcmp (XSTR (XEXP (link
, 0), 0), name
))
3694 space
[ndim
].num_values
++;
3695 *prev
= XEXP (link
, 1);
3696 XEXP (link
, 1) = space
[ndim
].values
;
3697 space
[ndim
].values
= link
;
3700 prev
= &XEXP (link
, 1);
3702 /* Add sufficient members to the list of values to make the list
3703 mutually exclusive and record the total size of the attribute
3705 total
*= add_values_to_cover (&space
[ndim
]);
3708 /* Sort the attribute space so that the attributes go from non-constant
3709 to constant and from most values to least values. */
3710 for (i
= 0; i
< ndim
; i
++)
3711 for (j
= ndim
- 1; j
> i
; j
--)
3712 if ((space
[j
-1].attr
->is_const
&& !space
[j
].attr
->is_const
)
3713 || space
[j
-1].num_values
< space
[j
].num_values
)
3715 struct dimension tmp
;
3717 space
[j
] = space
[j
- 1];
3721 /* Establish the initial current value. */
3722 for (i
= 0; i
< ndim
; i
++)
3723 space
[i
].current_value
= space
[i
].values
;
3725 condtest
= (rtx
*) xmalloc (total
* sizeof (rtx
));
3726 condval
= (rtx
*) xmalloc (total
* sizeof (rtx
));
3728 /* Expand the tests and values by iterating over all values in the
3732 condtest
[i
] = test_for_current_value (space
, ndim
);
3733 condval
[i
] = simplify_with_current_value (exp
, space
, ndim
);
3734 if (! increment_current_value (space
, ndim
))
3740 /* We are now finished with the original expression. */
3741 unmark_used_attributes (0, space
, ndim
);
3744 /* Find the most used constant value and make that the default. */
3746 for (i
= num_marks
= 0; i
< total
; i
++)
3747 if (GET_CODE (condval
[i
]) == CONST_STRING
3748 && ! MEM_VOLATILE_P (condval
[i
]))
3750 /* Mark the unmarked constant value and count how many are marked. */
3751 MEM_VOLATILE_P (condval
[i
]) = 1;
3752 for (j
= new_marks
= 0; j
< total
; j
++)
3753 if (GET_CODE (condval
[j
]) == CONST_STRING
3754 && MEM_VOLATILE_P (condval
[j
]))
3756 if (new_marks
- num_marks
> most_tests
)
3758 most_tests
= new_marks
- num_marks
;
3759 defval
= condval
[i
];
3761 num_marks
= new_marks
;
3763 /* Clear all the marks. */
3764 for (i
= 0; i
< total
; i
++)
3765 MEM_VOLATILE_P (condval
[i
]) = 0;
3767 /* Give up if nothing is constant. */
3771 /* If all values are the default, use that. */
3772 else if (total
== most_tests
)
3775 /* Make a COND with the most common constant value the default. (A more
3776 complex method where tests with the same value were combined didn't
3777 seem to improve things.) */
3780 condexp
= rtx_alloc (COND
);
3781 XVEC (condexp
, 0) = rtvec_alloc ((total
- most_tests
) * 2);
3782 XEXP (condexp
, 1) = defval
;
3783 for (i
= j
= 0; i
< total
; i
++)
3784 if (condval
[i
] != defval
)
3786 XVECEXP (condexp
, 0, 2 * j
) = condtest
[i
];
3787 XVECEXP (condexp
, 0, 2 * j
+ 1) = condval
[i
];
3797 /* Set the MEM_VOLATILE_P flag for all EQ_ATTR expressions in EXP and
3798 verify that EXP can be simplified to a constant term if all the EQ_ATTR
3799 tests have known value. */
3802 find_and_mark_used_attributes (exp
, terms
, nterms
)
3808 switch (GET_CODE (exp
))
3811 if (! MEM_VOLATILE_P (exp
))
3813 rtx link
= rtx_alloc (EXPR_LIST
);
3814 XEXP (link
, 0) = exp
;
3815 XEXP (link
, 1) = *terms
;
3818 MEM_VOLATILE_P (exp
) = 1;
3827 if (! find_and_mark_used_attributes (XEXP (exp
, 2), terms
, nterms
))
3831 if (! find_and_mark_used_attributes (XEXP (exp
, 1), terms
, nterms
))
3834 if (! find_and_mark_used_attributes (XEXP (exp
, 0), terms
, nterms
))
3839 for (i
= 0; i
< XVECLEN (exp
, 0); i
++)
3840 if (! find_and_mark_used_attributes (XVECEXP (exp
, 0, i
), terms
, nterms
))
3842 if (! find_and_mark_used_attributes (XEXP (exp
, 1), terms
, nterms
))
3851 /* Clear the MEM_VOLATILE_P flag in all EQ_ATTR expressions on LIST and
3852 in the values of the NDIM-dimensional attribute space SPACE. */
3855 unmark_used_attributes (list
, space
, ndim
)
3857 struct dimension
*space
;
3863 for (i
= 0; i
< ndim
; i
++)
3864 unmark_used_attributes (space
[i
].values
, 0, 0);
3866 for (link
= list
; link
; link
= XEXP (link
, 1))
3868 exp
= XEXP (link
, 0);
3869 if (GET_CODE (exp
) == EQ_ATTR
)
3870 MEM_VOLATILE_P (exp
) = 0;
3874 /* Update the attribute dimension DIM so that all values of the attribute
3875 are tested. Return the updated number of values. */
3878 add_values_to_cover (dim
)
3879 struct dimension
*dim
;
3881 struct attr_value
*av
;
3882 rtx exp
, link
, *prev
;
3885 for (av
= dim
->attr
->first_value
; av
; av
= av
->next
)
3886 if (GET_CODE (av
->value
) == CONST_STRING
)
3889 if (nalt
< dim
->num_values
)
3891 else if (nalt
== dim
->num_values
)
3894 else if (nalt
* 2 < dim
->num_values
* 3)
3896 /* Most all the values of the attribute are used, so add all the unused
3898 prev
= &dim
->values
;
3899 for (link
= dim
->values
; link
; link
= *prev
)
3900 prev
= &XEXP (link
, 1);
3902 for (av
= dim
->attr
->first_value
; av
; av
= av
->next
)
3903 if (GET_CODE (av
->value
) == CONST_STRING
)
3905 exp
= attr_eq (dim
->attr
->name
, XSTR (av
->value
, 0));
3906 if (MEM_VOLATILE_P (exp
))
3909 link
= rtx_alloc (EXPR_LIST
);
3910 XEXP (link
, 0) = exp
;
3913 prev
= &XEXP (link
, 1);
3915 dim
->num_values
= nalt
;
3919 rtx orexp
= false_rtx
;
3921 /* Very few values are used, so compute a mutually exclusive
3922 expression. (We could do this for numeric values if that becomes
3924 prev
= &dim
->values
;
3925 for (link
= dim
->values
; link
; link
= *prev
)
3927 orexp
= insert_right_side (IOR
, orexp
, XEXP (link
, 0), -2, -2);
3928 prev
= &XEXP (link
, 1);
3930 link
= rtx_alloc (EXPR_LIST
);
3931 XEXP (link
, 0) = attr_rtx (NOT
, orexp
);
3936 return dim
->num_values
;
3939 /* Increment the current value for the NDIM-dimensional attribute space SPACE
3940 and return FALSE if the increment overflowed. */
3943 increment_current_value (space
, ndim
)
3944 struct dimension
*space
;
3949 for (i
= ndim
- 1; i
>= 0; i
--)
3951 if ((space
[i
].current_value
= XEXP (space
[i
].current_value
, 1)) == 0)
3952 space
[i
].current_value
= space
[i
].values
;
3959 /* Construct an expression corresponding to the current value for the
3960 NDIM-dimensional attribute space SPACE. */
3963 test_for_current_value (space
, ndim
)
3964 struct dimension
*space
;
3970 for (i
= 0; i
< ndim
; i
++)
3971 exp
= insert_right_side (AND
, exp
, XEXP (space
[i
].current_value
, 0),
3977 /* Given the current value of the NDIM-dimensional attribute space SPACE,
3978 set the corresponding EQ_ATTR expressions to that value and reduce
3979 the expression EXP as much as possible. On input [and output], all
3980 known EQ_ATTR expressions are set to FALSE. */
3983 simplify_with_current_value (exp
, space
, ndim
)
3985 struct dimension
*space
;
3991 /* Mark each current value as TRUE. */
3992 for (i
= 0; i
< ndim
; i
++)
3994 x
= XEXP (space
[i
].current_value
, 0);
3995 if (GET_CODE (x
) == EQ_ATTR
)
3996 MEM_VOLATILE_P (x
) = 0;
3999 exp
= simplify_with_current_value_aux (exp
);
4001 /* Change each current value back to FALSE. */
4002 for (i
= 0; i
< ndim
; i
++)
4004 x
= XEXP (space
[i
].current_value
, 0);
4005 if (GET_CODE (x
) == EQ_ATTR
)
4006 MEM_VOLATILE_P (x
) = 1;
4012 /* Reduce the expression EXP based on the MEM_VOLATILE_P settings of
4013 all EQ_ATTR expressions. */
4016 simplify_with_current_value_aux (exp
)
4022 switch (GET_CODE (exp
))
4025 if (MEM_VOLATILE_P (exp
))
4034 cond
= simplify_with_current_value_aux (XEXP (exp
, 0));
4035 if (cond
== true_rtx
)
4036 return simplify_with_current_value_aux (XEXP (exp
, 1));
4037 else if (cond
== false_rtx
)
4038 return simplify_with_current_value_aux (XEXP (exp
, 2));
4040 return attr_rtx (IF_THEN_ELSE
, cond
,
4041 simplify_with_current_value_aux (XEXP (exp
, 1)),
4042 simplify_with_current_value_aux (XEXP (exp
, 2)));
4045 cond
= simplify_with_current_value_aux (XEXP (exp
, 1));
4046 if (cond
== true_rtx
)
4048 else if (cond
== false_rtx
)
4049 return simplify_with_current_value_aux (XEXP (exp
, 0));
4051 return attr_rtx (IOR
, cond
,
4052 simplify_with_current_value_aux (XEXP (exp
, 0)));
4055 cond
= simplify_with_current_value_aux (XEXP (exp
, 1));
4056 if (cond
== true_rtx
)
4057 return simplify_with_current_value_aux (XEXP (exp
, 0));
4058 else if (cond
== false_rtx
)
4061 return attr_rtx (AND
, cond
,
4062 simplify_with_current_value_aux (XEXP (exp
, 0)));
4065 cond
= simplify_with_current_value_aux (XEXP (exp
, 0));
4066 if (cond
== true_rtx
)
4068 else if (cond
== false_rtx
)
4071 return attr_rtx (NOT
, cond
);
4074 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
4076 cond
= simplify_with_current_value_aux (XVECEXP (exp
, 0, i
));
4077 if (cond
== true_rtx
)
4078 return simplify_with_current_value_aux (XVECEXP (exp
, 0, i
+ 1));
4079 else if (cond
== false_rtx
)
4082 abort (); /* With all EQ_ATTR's of known value, a case should
4083 have been selected. */
4085 return simplify_with_current_value_aux (XEXP (exp
, 1));
4092 /* Clear the MEM_IN_STRUCT_P flag in EXP and its subexpressions. */
4095 clear_struct_flag (x
)
4103 MEM_IN_STRUCT_P (x
) = 0;
4104 if (RTX_UNCHANGING_P (x
))
4107 code
= GET_CODE (x
);
4127 /* Compare the elements. If any pair of corresponding elements
4128 fail to match, return 0 for the whole things. */
4130 fmt
= GET_RTX_FORMAT (code
);
4131 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
4137 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
4138 clear_struct_flag (XVECEXP (x
, i
, j
));
4142 clear_struct_flag (XEXP (x
, i
));
4148 /* Return the number of RTX objects making up the expression X.
4149 But if we count more than MAX objects, stop counting. */
4152 count_sub_rtxs (x
, max
)
4162 code
= GET_CODE (x
);
4182 /* Compare the elements. If any pair of corresponding elements
4183 fail to match, return 0 for the whole things. */
4185 fmt
= GET_RTX_FORMAT (code
);
4186 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
4195 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
4196 total
+= count_sub_rtxs (XVECEXP (x
, i
, j
), max
);
4200 total
+= count_sub_rtxs (XEXP (x
, i
), max
);
4208 /* Create table entries for DEFINE_ATTR. */
4211 gen_attr (exp
, lineno
)
4215 struct attr_desc
*attr
;
4216 struct attr_value
*av
;
4217 const char *name_ptr
;
4220 /* Make a new attribute structure. Check for duplicate by looking at
4221 attr->default_val, since it is initialized by this routine. */
4222 attr
= find_attr (XSTR (exp
, 0), 1);
4223 if (attr
->default_val
)
4225 message_with_line (lineno
, "duplicate definition for attribute %s",
4227 message_with_line (attr
->lineno
, "previous definition");
4231 attr
->lineno
= lineno
;
4233 if (*XSTR (exp
, 1) == '\0')
4234 attr
->is_numeric
= 1;
4237 name_ptr
= XSTR (exp
, 1);
4238 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
4240 av
= (struct attr_value
*) oballoc (sizeof (struct attr_value
));
4241 av
->value
= attr_rtx (CONST_STRING
, p
);
4242 av
->next
= attr
->first_value
;
4243 attr
->first_value
= av
;
4244 av
->first_insn
= NULL
;
4246 av
->has_asm_insn
= 0;
4250 if (GET_CODE (XEXP (exp
, 2)) == CONST
)
4253 if (attr
->is_numeric
)
4255 message_with_line (lineno
,
4256 "constant attributes may not take numeric values");
4260 /* Get rid of the CONST node. It is allowed only at top-level. */
4261 XEXP (exp
, 2) = XEXP (XEXP (exp
, 2), 0);
4264 if (! strcmp (attr
->name
, "length") && ! attr
->is_numeric
)
4266 message_with_line (lineno
,
4267 "`length' attribute must take numeric values");
4271 /* Set up the default value. */
4272 XEXP (exp
, 2) = check_attr_value (XEXP (exp
, 2), attr
);
4273 attr
->default_val
= get_attr_value (XEXP (exp
, 2), attr
, -2);
4276 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
4277 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
4278 number of alternatives as this should be checked elsewhere. */
4281 count_alternatives (exp
)
4287 if (GET_CODE (exp
) == MATCH_OPERAND
)
4288 return n_comma_elts (XSTR (exp
, 2));
4290 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
4291 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
4296 n
= count_alternatives (XEXP (exp
, i
));
4303 if (XVEC (exp
, i
) != NULL
)
4304 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
4306 n
= count_alternatives (XVECEXP (exp
, i
, j
));
4315 /* Returns non-zero if the given expression contains an EQ_ATTR with the
4316 `alternative' attribute. */
4319 compares_alternatives_p (exp
)
4325 if (GET_CODE (exp
) == EQ_ATTR
&& XSTR (exp
, 0) == alternative_name
)
4328 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
4329 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
4334 if (compares_alternatives_p (XEXP (exp
, i
)))
4339 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
4340 if (compares_alternatives_p (XVECEXP (exp
, i
, j
)))
4348 /* Returns non-zero is INNER is contained in EXP. */
4351 contained_in_p (inner
, exp
)
4358 if (rtx_equal_p (inner
, exp
))
4361 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
4362 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
4367 if (contained_in_p (inner
, XEXP (exp
, i
)))
4372 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
4373 if (contained_in_p (inner
, XVECEXP (exp
, i
, j
)))
4381 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
4384 gen_insn (exp
, lineno
)
4388 struct insn_def
*id
;
4390 id
= (struct insn_def
*) oballoc (sizeof (struct insn_def
));
4394 id
->lineno
= lineno
;
4396 switch (GET_CODE (exp
))
4399 id
->insn_code
= insn_code_number
;
4400 id
->insn_index
= insn_index_number
;
4401 id
->num_alternatives
= count_alternatives (exp
);
4402 if (id
->num_alternatives
== 0)
4403 id
->num_alternatives
= 1;
4407 case DEFINE_PEEPHOLE
:
4408 id
->insn_code
= insn_code_number
;
4409 id
->insn_index
= insn_index_number
;
4410 id
->num_alternatives
= count_alternatives (exp
);
4411 if (id
->num_alternatives
== 0)
4412 id
->num_alternatives
= 1;
4416 case DEFINE_ASM_ATTRIBUTES
:
4418 id
->insn_index
= -1;
4419 id
->num_alternatives
= 1;
4421 got_define_asm_attributes
= 1;
4429 /* Process a DEFINE_DELAY. Validate the vector length, check if annul
4430 true or annul false is specified, and make a `struct delay_desc'. */
4433 gen_delay (def
, lineno
)
4437 struct delay_desc
*delay
;
4440 if (XVECLEN (def
, 1) % 3 != 0)
4442 message_with_line (lineno
,
4443 "number of elements in DEFINE_DELAY must be multiple of three");
4448 for (i
= 0; i
< XVECLEN (def
, 1); i
+= 3)
4450 if (XVECEXP (def
, 1, i
+ 1))
4451 have_annul_true
= 1;
4452 if (XVECEXP (def
, 1, i
+ 2))
4453 have_annul_false
= 1;
4456 delay
= (struct delay_desc
*) oballoc (sizeof (struct delay_desc
));
4458 delay
->num
= ++num_delays
;
4459 delay
->next
= delays
;
4460 delay
->lineno
= lineno
;
4464 /* Process a DEFINE_FUNCTION_UNIT.
4466 This gives information about a function unit contained in the CPU.
4467 We fill in a `struct function_unit_op' and a `struct function_unit'
4468 with information used later by `expand_unit'. */
4471 gen_unit (def
, lineno
)
4475 struct function_unit
*unit
;
4476 struct function_unit_op
*op
;
4477 const char *name
= XSTR (def
, 0);
4478 int multiplicity
= XINT (def
, 1);
4479 int simultaneity
= XINT (def
, 2);
4480 rtx condexp
= XEXP (def
, 3);
4481 int ready_cost
= MAX (XINT (def
, 4), 1);
4482 int issue_delay
= MAX (XINT (def
, 5), 1);
4484 /* See if we have already seen this function unit. If so, check that
4485 the multiplicity and simultaneity values are the same. If not, make
4486 a structure for this function unit. */
4487 for (unit
= units
; unit
; unit
= unit
->next
)
4488 if (! strcmp (unit
->name
, name
))
4490 if (unit
->multiplicity
!= multiplicity
4491 || unit
->simultaneity
!= simultaneity
)
4493 message_with_line (lineno
,
4494 "differing specifications given for function unit %s",
4496 message_with_line (unit
->first_lineno
, "previous definition");
4505 unit
= (struct function_unit
*) oballoc (sizeof (struct function_unit
));
4507 unit
->multiplicity
= multiplicity
;
4508 unit
->simultaneity
= simultaneity
;
4509 unit
->issue_delay
.min
= unit
->issue_delay
.max
= issue_delay
;
4510 unit
->num
= num_units
++;
4511 unit
->num_opclasses
= 0;
4512 unit
->condexp
= false_rtx
;
4515 unit
->first_lineno
= lineno
;
4519 /* Make a new operation class structure entry and initialize it. */
4520 op
= (struct function_unit_op
*) oballoc (sizeof (struct function_unit_op
));
4521 op
->condexp
= condexp
;
4522 op
->num
= unit
->num_opclasses
++;
4523 op
->ready
= ready_cost
;
4524 op
->issue_delay
= issue_delay
;
4525 op
->next
= unit
->ops
;
4526 op
->lineno
= lineno
;
4528 num_unit_opclasses
++;
4530 /* Set our issue expression based on whether or not an optional conflict
4531 vector was specified. */
4534 /* Compute the IOR of all the specified expressions. */
4535 rtx orexp
= false_rtx
;
4538 for (i
= 0; i
< XVECLEN (def
, 6); i
++)
4539 orexp
= insert_right_side (IOR
, orexp
, XVECEXP (def
, 6, i
), -2, -2);
4541 op
->conflict_exp
= orexp
;
4542 extend_range (&unit
->issue_delay
, 1, issue_delay
);
4546 op
->conflict_exp
= true_rtx
;
4547 extend_range (&unit
->issue_delay
, issue_delay
, issue_delay
);
4550 /* Merge our conditional into that of the function unit so we can determine
4551 which insns are used by the function unit. */
4552 unit
->condexp
= insert_right_side (IOR
, unit
->condexp
, op
->condexp
, -2, -2);
4555 /* Given a piece of RTX, print a C expression to test its truth value.
4556 We use AND and IOR both for logical and bit-wise operations, so
4557 interpret them as logical unless they are inside a comparison expression.
4558 The first bit of FLAGS will be non-zero in that case.
4560 Set the second bit of FLAGS to make references to attribute values use
4561 a cached local variable instead of calling a function. */
4564 write_test_expr (exp
, flags
)
4568 int comparison_operator
= 0;
4570 struct attr_desc
*attr
;
4572 /* In order not to worry about operator precedence, surround our part of
4573 the expression with parentheses. */
4576 code
= GET_CODE (exp
);
4579 /* Binary operators. */
4581 case GE
: case GT
: case GEU
: case GTU
:
4582 case LE
: case LT
: case LEU
: case LTU
:
4583 comparison_operator
= 1;
4585 case PLUS
: case MINUS
: case MULT
: case DIV
: case MOD
:
4586 case AND
: case IOR
: case XOR
:
4587 case ASHIFT
: case LSHIFTRT
: case ASHIFTRT
:
4588 write_test_expr (XEXP (exp
, 0), flags
| comparison_operator
);
4604 printf (" >= (unsigned) ");
4607 printf (" > (unsigned) ");
4616 printf (" <= (unsigned) ");
4619 printf (" < (unsigned) ");
4662 write_test_expr (XEXP (exp
, 1), flags
| comparison_operator
);
4666 /* Special-case (not (eq_attrq "alternative" "x")) */
4667 if (! (flags
& 1) && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
4668 && XSTR (XEXP (exp
, 0), 0) == alternative_name
)
4670 printf ("which_alternative != %s", XSTR (XEXP (exp
, 0), 1));
4674 /* Otherwise, fall through to normal unary operator. */
4676 /* Unary operators. */
4696 write_test_expr (XEXP (exp
, 0), flags
);
4699 /* Comparison test of an attribute with a value. Most of these will
4700 have been removed by optimization. Handle "alternative"
4701 specially and give error if EQ_ATTR present inside a comparison. */
4704 fatal ("EQ_ATTR not valid inside comparison");
4706 if (XSTR (exp
, 0) == alternative_name
)
4708 printf ("which_alternative == %s", XSTR (exp
, 1));
4712 attr
= find_attr (XSTR (exp
, 0), 0);
4716 /* Now is the time to expand the value of a constant attribute. */
4719 write_test_expr (evaluate_eq_attr (exp
, attr
->default_val
->value
,
4726 printf ("attr_%s", attr
->name
);
4728 printf ("get_attr_%s (insn)", attr
->name
);
4730 write_attr_valueq (attr
, XSTR (exp
, 1));
4734 /* Comparison test of flags for define_delays. */
4737 fatal ("ATTR_FLAG not valid inside comparison");
4738 printf ("(flags & ATTR_FLAG_%s) != 0", XSTR (exp
, 0));
4741 /* See if an operand matches a predicate. */
4743 /* If only a mode is given, just ensure the mode matches the operand.
4744 If neither a mode nor predicate is given, error. */
4745 if (XSTR (exp
, 1) == NULL
|| *XSTR (exp
, 1) == '\0')
4747 if (GET_MODE (exp
) == VOIDmode
)
4748 fatal ("null MATCH_OPERAND specified as test");
4750 printf ("GET_MODE (operands[%d]) == %smode",
4751 XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
4754 printf ("%s (operands[%d], %smode)",
4755 XSTR (exp
, 1), XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
4759 printf ("%s (insn)", XSTR (exp
, 0));
4762 /* Constant integer. */
4764 printf (HOST_WIDE_INT_PRINT_DEC
, XWINT (exp
, 0));
4767 /* A random C expression. */
4769 printf ("%s", XSTR (exp
, 0));
4772 /* The address of the branch target. */
4774 printf ("INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
4775 XINT (exp
, 0), XINT (exp
, 0), XINT (exp
, 0));
4779 /* The address of the current insn. We implement this actually as the
4780 address of the current insn for backward branches, but the last
4781 address of the next insn for forward branches, and both with
4782 adjustments that account for the worst-case possible stretching of
4783 intervening alignments between this insn and its destination. */
4784 printf ("insn_current_reference_address (insn)");
4788 printf ("%s", XSTR (exp
, 0));
4792 write_test_expr (XEXP (exp
, 0), flags
& 2);
4794 write_test_expr (XEXP (exp
, 1), flags
| 1);
4796 write_test_expr (XEXP (exp
, 2), flags
| 1);
4800 fatal ("bad RTX code `%s' in attribute calculation\n",
4801 GET_RTX_NAME (code
));
4807 /* Given an attribute value, return the maximum CONST_STRING argument
4808 encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */
4811 max_attr_value (exp
, unknownp
)
4818 switch (GET_CODE (exp
))
4821 current_max
= atoi (XSTR (exp
, 0));
4825 current_max
= max_attr_value (XEXP (exp
, 1), unknownp
);
4826 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
4828 n
= max_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
4829 if (n
> current_max
)
4835 current_max
= max_attr_value (XEXP (exp
, 1), unknownp
);
4836 n
= max_attr_value (XEXP (exp
, 2), unknownp
);
4837 if (n
> current_max
)
4843 current_max
= INT_MAX
;
4850 /* Given an attribute value, return the result of ORing together all
4851 CONST_STRING arguments encountered. Set *UNKNOWNP and return -1
4852 if the numeric value is not known. */
4855 or_attr_value (exp
, unknownp
)
4862 switch (GET_CODE (exp
))
4865 current_or
= atoi (XSTR (exp
, 0));
4869 current_or
= or_attr_value (XEXP (exp
, 1), unknownp
);
4870 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
4871 current_or
|= or_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
4875 current_or
= or_attr_value (XEXP (exp
, 1), unknownp
);
4876 current_or
|= or_attr_value (XEXP (exp
, 2), unknownp
);
4888 /* Scan an attribute value, possibly a conditional, and record what actions
4889 will be required to do any conditional tests in it.
4892 `must_extract' if we need to extract the insn operands
4893 `must_constrain' if we must compute `which_alternative'
4894 `address_used' if an address expression was used
4895 `length_used' if an (eq_attr "length" ...) was used
4899 walk_attr_value (exp
)
4909 code
= GET_CODE (exp
);
4913 if (! RTX_UNCHANGING_P (exp
))
4914 /* Since this is an arbitrary expression, it can look at anything.
4915 However, constant expressions do not depend on any particular
4917 must_extract
= must_constrain
= 1;
4925 if (XSTR (exp
, 0) == alternative_name
)
4926 must_extract
= must_constrain
= 1;
4927 else if (strcmp (XSTR (exp
, 0), "length") == 0)
4947 for (i
= 0, fmt
= GET_RTX_FORMAT (code
); i
< GET_RTX_LENGTH (code
); i
++)
4952 walk_attr_value (XEXP (exp
, i
));
4956 if (XVEC (exp
, i
) != NULL
)
4957 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
4958 walk_attr_value (XVECEXP (exp
, i
, j
));
4963 /* Write out a function to obtain the attribute for a given INSN. */
4966 write_attr_get (attr
)
4967 struct attr_desc
*attr
;
4969 struct attr_value
*av
, *common_av
;
4971 /* Find the most used attribute value. Handle that as the `default' of the
4972 switch we will generate. */
4973 common_av
= find_most_used (attr
);
4975 /* Write out prototype of function. */
4976 if (!attr
->is_numeric
)
4977 printf ("extern enum attr_%s ", attr
->name
);
4978 else if (attr
->unsigned_p
)
4979 printf ("extern unsigned int ");
4981 printf ("extern int ");
4982 /* If the attribute name starts with a star, the remainder is the name of
4983 the subroutine to use, instead of `get_attr_...'. */
4984 if (attr
->name
[0] == '*')
4985 printf ("%s PARAMS ((rtx));\n", &attr
->name
[1]);
4987 printf ("get_attr_%s PARAMS ((%s));\n", attr
->name
,
4988 (attr
->is_const
? "void" : "rtx"));
4990 /* Write out start of function, then all values with explicit `case' lines,
4991 then a `default', then the value with the most uses. */
4992 if (!attr
->is_numeric
)
4993 printf ("enum attr_%s\n", attr
->name
);
4994 else if (attr
->unsigned_p
)
4995 printf ("unsigned int\n");
4999 /* If the attribute name starts with a star, the remainder is the name of
5000 the subroutine to use, instead of `get_attr_...'. */
5001 if (attr
->name
[0] == '*')
5002 printf ("%s (insn)\n", &attr
->name
[1]);
5003 else if (attr
->is_const
== 0)
5004 printf ("get_attr_%s (insn)\n", attr
->name
);
5007 printf ("get_attr_%s ()\n", attr
->name
);
5010 for (av
= attr
->first_value
; av
; av
= av
->next
)
5011 if (av
->num_insns
!= 0)
5012 write_attr_set (attr
, 2, av
->value
, "return", ";",
5013 true_rtx
, av
->first_insn
->insn_code
,
5014 av
->first_insn
->insn_index
);
5020 printf (" rtx insn;\n");
5023 if (GET_CODE (common_av
->value
) == FFS
)
5025 rtx p
= XEXP (common_av
->value
, 0);
5027 /* No need to emit code to abort if the insn is unrecognized; the
5028 other get_attr_foo functions will do that when we call them. */
5030 write_toplevel_expr (p
);
5032 printf ("\n if (accum && accum == (accum & -accum))\n");
5034 printf (" int i;\n");
5035 printf (" for (i = 0; accum >>= 1; ++i) continue;\n");
5036 printf (" accum = i;\n");
5037 printf (" }\n else\n");
5038 printf (" accum = ~accum;\n");
5039 printf (" return accum;\n}\n\n");
5043 printf (" switch (recog_memoized (insn))\n");
5046 for (av
= attr
->first_value
; av
; av
= av
->next
)
5047 if (av
!= common_av
)
5048 write_attr_case (attr
, av
, 1, "return", ";", 4, true_rtx
);
5050 write_attr_case (attr
, common_av
, 0, "return", ";", 4, true_rtx
);
5051 printf (" }\n}\n\n");
5055 /* Given an AND tree of known true terms (because we are inside an `if' with
5056 that as the condition or are in an `else' clause) and an expression,
5057 replace any known true terms with TRUE. Use `simplify_and_tree' to do
5058 the bulk of the work. */
5061 eliminate_known_true (known_true
, exp
, insn_code
, insn_index
)
5064 int insn_code
, insn_index
;
5068 known_true
= SIMPLIFY_TEST_EXP (known_true
, insn_code
, insn_index
);
5070 if (GET_CODE (known_true
) == AND
)
5072 exp
= eliminate_known_true (XEXP (known_true
, 0), exp
,
5073 insn_code
, insn_index
);
5074 exp
= eliminate_known_true (XEXP (known_true
, 1), exp
,
5075 insn_code
, insn_index
);
5080 exp
= simplify_and_tree (exp
, &term
, insn_code
, insn_index
);
5086 /* Write out a series of tests and assignment statements to perform tests and
5087 sets of an attribute value. We are passed an indentation amount and prefix
5088 and suffix strings to write around each attribute value (e.g., "return"
5092 write_attr_set (attr
, indent
, value
, prefix
, suffix
, known_true
,
5093 insn_code
, insn_index
)
5094 struct attr_desc
*attr
;
5100 int insn_code
, insn_index
;
5102 if (GET_CODE (value
) == COND
)
5104 /* Assume the default value will be the default of the COND unless we
5105 find an always true expression. */
5106 rtx default_val
= XEXP (value
, 1);
5107 rtx our_known_true
= known_true
;
5112 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
5117 testexp
= eliminate_known_true (our_known_true
,
5118 XVECEXP (value
, 0, i
),
5119 insn_code
, insn_index
);
5120 newexp
= attr_rtx (NOT
, testexp
);
5121 newexp
= insert_right_side (AND
, our_known_true
, newexp
,
5122 insn_code
, insn_index
);
5124 /* If the test expression is always true or if the next `known_true'
5125 expression is always false, this is the last case, so break
5126 out and let this value be the `else' case. */
5127 if (testexp
== true_rtx
|| newexp
== false_rtx
)
5129 default_val
= XVECEXP (value
, 0, i
+ 1);
5133 /* Compute the expression to pass to our recursive call as being
5135 inner_true
= insert_right_side (AND
, our_known_true
,
5136 testexp
, insn_code
, insn_index
);
5138 /* If this is always false, skip it. */
5139 if (inner_true
== false_rtx
)
5142 write_indent (indent
);
5143 printf ("%sif ", first_if
? "" : "else ");
5145 write_test_expr (testexp
, 0);
5147 write_indent (indent
+ 2);
5150 write_attr_set (attr
, indent
+ 4,
5151 XVECEXP (value
, 0, i
+ 1), prefix
, suffix
,
5152 inner_true
, insn_code
, insn_index
);
5153 write_indent (indent
+ 2);
5155 our_known_true
= newexp
;
5160 write_indent (indent
);
5162 write_indent (indent
+ 2);
5166 write_attr_set (attr
, first_if
? indent
: indent
+ 4, default_val
,
5167 prefix
, suffix
, our_known_true
, insn_code
, insn_index
);
5171 write_indent (indent
+ 2);
5177 write_indent (indent
);
5178 printf ("%s ", prefix
);
5179 write_attr_value (attr
, value
);
5180 printf ("%s\n", suffix
);
5184 /* Write out the computation for one attribute value. */
5187 write_attr_case (attr
, av
, write_case_lines
, prefix
, suffix
, indent
,
5189 struct attr_desc
*attr
;
5190 struct attr_value
*av
;
5191 int write_case_lines
;
5192 const char *prefix
, *suffix
;
5196 struct insn_ent
*ie
;
5198 if (av
->num_insns
== 0)
5201 if (av
->has_asm_insn
)
5203 write_indent (indent
);
5204 printf ("case -1:\n");
5205 write_indent (indent
+ 2);
5206 printf ("if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
5207 write_indent (indent
+ 2);
5208 printf (" && asm_noperands (PATTERN (insn)) < 0)\n");
5209 write_indent (indent
+ 2);
5210 printf (" fatal_insn_not_found (insn);\n");
5213 if (write_case_lines
)
5215 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
5216 if (ie
->insn_code
!= -1)
5218 write_indent (indent
);
5219 printf ("case %d:\n", ie
->insn_code
);
5224 write_indent (indent
);
5225 printf ("default:\n");
5228 /* See what we have to do to output this value. */
5229 must_extract
= must_constrain
= address_used
= 0;
5230 walk_attr_value (av
->value
);
5234 write_indent (indent
+ 2);
5235 printf ("extract_constrain_insn_cached (insn);\n");
5237 else if (must_extract
)
5239 write_indent (indent
+ 2);
5240 printf ("extract_insn_cached (insn);\n");
5243 write_attr_set (attr
, indent
+ 2, av
->value
, prefix
, suffix
,
5244 known_true
, av
->first_insn
->insn_code
,
5245 av
->first_insn
->insn_index
);
5247 if (strncmp (prefix
, "return", 6))
5249 write_indent (indent
+ 2);
5250 printf ("break;\n");
5255 /* Search for uses of non-const attributes and write code to cache them. */
5258 write_expr_attr_cache (p
, attr
)
5260 struct attr_desc
*attr
;
5265 if (GET_CODE (p
) == EQ_ATTR
)
5267 if (XSTR (p
, 0) != attr
->name
)
5270 if (!attr
->is_numeric
)
5271 printf (" enum attr_%s ", attr
->name
);
5272 else if (attr
->unsigned_p
)
5273 printf (" unsigned int ");
5277 printf ("attr_%s = get_attr_%s (insn);\n", attr
->name
, attr
->name
);
5281 fmt
= GET_RTX_FORMAT (GET_CODE (p
));
5282 ie
= GET_RTX_LENGTH (GET_CODE (p
));
5283 for (i
= 0; i
< ie
; i
++)
5288 if (write_expr_attr_cache (XEXP (p
, i
), attr
))
5293 je
= XVECLEN (p
, i
);
5294 for (j
= 0; j
< je
; ++j
)
5295 if (write_expr_attr_cache (XVECEXP (p
, i
, j
), attr
))
5304 /* Evaluate an expression at top level. A front end to write_test_expr,
5305 in which we cache attribute values and break up excessively large
5306 expressions to cater to older compilers. */
5309 write_toplevel_expr (p
)
5312 struct attr_desc
*attr
;
5315 for (i
= 0; i
< MAX_ATTRS_INDEX
; ++i
)
5316 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
5317 if (!attr
->is_const
)
5318 write_expr_attr_cache (p
, attr
);
5320 printf (" unsigned long accum = 0;\n\n");
5322 while (GET_CODE (p
) == IOR
)
5325 if (GET_CODE (XEXP (p
, 0)) == IOR
)
5326 e
= XEXP (p
, 1), p
= XEXP (p
, 0);
5328 e
= XEXP (p
, 0), p
= XEXP (p
, 1);
5330 printf (" accum |= ");
5331 write_test_expr (e
, 3);
5334 printf (" accum |= ");
5335 write_test_expr (p
, 3);
5339 /* Utilities to write names in various forms. */
5342 write_unit_name (prefix
, num
, suffix
)
5347 struct function_unit
*unit
;
5349 for (unit
= units
; unit
; unit
= unit
->next
)
5350 if (unit
->num
== num
)
5352 printf ("%s%s%s", prefix
, unit
->name
, suffix
);
5356 printf ("%s<unknown>%s", prefix
, suffix
);
5360 write_attr_valueq (attr
, s
)
5361 struct attr_desc
*attr
;
5364 if (attr
->is_numeric
)
5370 /* Make the blockage range values and function units used values easier
5372 if (attr
->func_units_p
)
5375 printf (" /* units: none */");
5377 write_unit_name (" /* units: ", num
, " */");
5381 const char *sep
= " /* units: ";
5382 for (i
= 0, num
= ~num
; num
; i
++, num
>>= 1)
5385 write_unit_name (sep
, i
, (num
== 1) ? " */" : "");
5391 else if (attr
->blockage_p
)
5392 printf (" /* min %d, max %d */", num
>> (HOST_BITS_PER_INT
/ 2),
5393 num
& ((1 << (HOST_BITS_PER_INT
/ 2)) - 1));
5395 else if (num
> 9 || num
< 0)
5396 printf (" /* 0x%x */", num
);
5400 write_upcase (attr
->name
);
5407 write_attr_value (attr
, value
)
5408 struct attr_desc
*attr
;
5413 switch (GET_CODE (value
))
5416 write_attr_valueq (attr
, XSTR (value
, 0));
5420 printf (HOST_WIDE_INT_PRINT_DEC
, INTVAL (value
));
5424 fputs (XSTR (value
, 0), stdout
);
5429 struct attr_desc
*attr2
= find_attr (XSTR (value
, 0), 0);
5430 printf ("get_attr_%s (%s)", attr2
->name
,
5431 (attr2
->is_const
? "" : "insn"));
5452 write_attr_value (attr
, XEXP (value
, 0));
5456 write_attr_value (attr
, XEXP (value
, 1));
5470 /* The argument of TOUPPER should not have side effects. */
5471 putchar (TOUPPER(*str
));
5477 write_indent (indent
)
5480 for (; indent
> 8; indent
-= 8)
5483 for (; indent
; indent
--)
5487 /* Write a subroutine that is given an insn that requires a delay slot, a
5488 delay slot ordinal, and a candidate insn. It returns non-zero if the
5489 candidate can be placed in the specified delay slot of the insn.
5491 We can write as many as three subroutines. `eligible_for_delay'
5492 handles normal delay slots, `eligible_for_annul_true' indicates that
5493 the specified insn can be annulled if the branch is true, and likewise
5494 for `eligible_for_annul_false'.
5496 KIND is a string distinguishing these three cases ("delay", "annul_true",
5497 or "annul_false"). */
5500 write_eligible_delay (kind
)
5503 struct delay_desc
*delay
;
5506 struct attr_desc
*attr
;
5507 struct attr_value
*av
, *common_av
;
5510 /* Compute the maximum number of delay slots required. We use the delay
5511 ordinal times this number plus one, plus the slot number as an index into
5512 the appropriate predicate to test. */
5514 for (delay
= delays
, max_slots
= 0; delay
; delay
= delay
->next
)
5515 if (XVECLEN (delay
->def
, 1) / 3 > max_slots
)
5516 max_slots
= XVECLEN (delay
->def
, 1) / 3;
5518 /* Write function prelude. */
5521 printf ("eligible_for_%s (delay_insn, slot, candidate_insn, flags)\n",
5523 printf (" rtx delay_insn ATTRIBUTE_UNUSED;\n");
5524 printf (" int slot;\n");
5525 printf (" rtx candidate_insn;\n");
5526 printf (" int flags ATTRIBUTE_UNUSED;\n");
5528 printf (" rtx insn;\n");
5530 printf (" if (slot >= %d)\n", max_slots
);
5531 printf (" abort ();\n");
5534 /* If more than one delay type, find out which type the delay insn is. */
5538 attr
= find_attr ("*delay_type", 0);
5541 common_av
= find_most_used (attr
);
5543 printf (" insn = delay_insn;\n");
5544 printf (" switch (recog_memoized (insn))\n");
5547 sprintf (str
, " * %d;\n break;", max_slots
);
5548 for (av
= attr
->first_value
; av
; av
= av
->next
)
5549 if (av
!= common_av
)
5550 write_attr_case (attr
, av
, 1, "slot +=", str
, 4, true_rtx
);
5552 write_attr_case (attr
, common_av
, 0, "slot +=", str
, 4, true_rtx
);
5555 /* Ensure matched. Otherwise, shouldn't have been called. */
5556 printf (" if (slot < %d)\n", max_slots
);
5557 printf (" abort ();\n\n");
5560 /* If just one type of delay slot, write simple switch. */
5561 if (num_delays
== 1 && max_slots
== 1)
5563 printf (" insn = candidate_insn;\n");
5564 printf (" switch (recog_memoized (insn))\n");
5567 attr
= find_attr ("*delay_1_0", 0);
5570 common_av
= find_most_used (attr
);
5572 for (av
= attr
->first_value
; av
; av
= av
->next
)
5573 if (av
!= common_av
)
5574 write_attr_case (attr
, av
, 1, "return", ";", 4, true_rtx
);
5576 write_attr_case (attr
, common_av
, 0, "return", ";", 4, true_rtx
);
5582 /* Write a nested CASE. The first indicates which condition we need to
5583 test, and the inner CASE tests the condition. */
5584 printf (" insn = candidate_insn;\n");
5585 printf (" switch (slot)\n");
5588 for (delay
= delays
; delay
; delay
= delay
->next
)
5589 for (i
= 0; i
< XVECLEN (delay
->def
, 1); i
+= 3)
5591 printf (" case %d:\n",
5592 (i
/ 3) + (num_delays
== 1 ? 0 : delay
->num
* max_slots
));
5593 printf (" switch (recog_memoized (insn))\n");
5596 sprintf (str
, "*%s_%d_%d", kind
, delay
->num
, i
/ 3);
5597 attr
= find_attr (str
, 0);
5600 common_av
= find_most_used (attr
);
5602 for (av
= attr
->first_value
; av
; av
= av
->next
)
5603 if (av
!= common_av
)
5604 write_attr_case (attr
, av
, 1, "return", ";", 8, true_rtx
);
5606 write_attr_case (attr
, common_av
, 0, "return", ";", 8, true_rtx
);
5610 printf (" default:\n");
5611 printf (" abort ();\n");
5618 /* Write routines to compute conflict cost for function units. Then write a
5619 table describing the available function units. */
5622 write_function_unit_info ()
5624 struct function_unit
*unit
;
5627 /* Write out conflict routines for function units. Don't bother writing
5628 one if there is only one issue delay value. */
5630 for (unit
= units
; unit
; unit
= unit
->next
)
5632 if (unit
->needs_blockage_function
)
5633 write_complex_function (unit
, "blockage", "block");
5635 /* If the minimum and maximum conflict costs are the same, there
5636 is only one value, so we don't need a function. */
5637 if (! unit
->needs_conflict_function
)
5639 unit
->default_cost
= make_numeric_value (unit
->issue_delay
.max
);
5643 /* The function first computes the case from the candidate insn. */
5644 unit
->default_cost
= make_numeric_value (0);
5645 write_complex_function (unit
, "conflict_cost", "cost");
5648 /* Now that all functions have been written, write the table describing
5649 the function units. The name is included for documentation purposes
5652 printf ("const struct function_unit_desc function_units[] = {\n");
5654 /* Write out the descriptions in numeric order, but don't force that order
5655 on the list. Doing so increases the runtime of genattrtab.c. */
5656 for (i
= 0; i
< num_units
; i
++)
5658 for (unit
= units
; unit
; unit
= unit
->next
)
5662 printf (" {\"%s\", %d, %d, %d, %s, %d, %s_unit_ready_cost, ",
5663 unit
->name
, 1 << unit
->num
, unit
->multiplicity
,
5664 unit
->simultaneity
, XSTR (unit
->default_cost
, 0),
5665 unit
->issue_delay
.max
, unit
->name
);
5667 if (unit
->needs_conflict_function
)
5668 printf ("%s_unit_conflict_cost, ", unit
->name
);
5672 printf ("%d, ", unit
->max_blockage
);
5674 if (unit
->needs_range_function
)
5675 printf ("%s_unit_blockage_range, ", unit
->name
);
5679 if (unit
->needs_blockage_function
)
5680 printf ("%s_unit_blockage", unit
->name
);
5691 write_complex_function (unit
, name
, connection
)
5692 struct function_unit
*unit
;
5693 const char *name
, *connection
;
5695 struct attr_desc
*case_attr
, *attr
;
5696 struct attr_value
*av
, *common_av
;
5702 printf ("static int %s_unit_%s PARAMS ((rtx, rtx));\n", unit
->name
, name
);
5703 printf ("static int\n");
5704 printf ("%s_unit_%s (executing_insn, candidate_insn)\n", unit
->name
, name
);
5705 printf (" rtx executing_insn;\n");
5706 printf (" rtx candidate_insn;\n");
5708 printf (" rtx insn;\n");
5709 printf (" int casenum;\n\n");
5710 printf (" insn = executing_insn;\n");
5711 printf (" switch (recog_memoized (insn))\n");
5714 /* Write the `switch' statement to get the case value. */
5715 if (strlen (unit
->name
) + sizeof "*_cases" > 256)
5717 sprintf (str
, "*%s_cases", unit
->name
);
5718 case_attr
= find_attr (str
, 0);
5721 common_av
= find_most_used (case_attr
);
5723 for (av
= case_attr
->first_value
; av
; av
= av
->next
)
5724 if (av
!= common_av
)
5725 write_attr_case (case_attr
, av
, 1,
5726 "casenum =", ";", 4, unit
->condexp
);
5728 write_attr_case (case_attr
, common_av
, 0,
5729 "casenum =", ";", 4, unit
->condexp
);
5732 /* Now write an outer switch statement on each case. Then write
5733 the tests on the executing function within each. */
5734 printf (" insn = candidate_insn;\n");
5735 printf (" switch (casenum)\n");
5738 for (i
= 0; i
< unit
->num_opclasses
; i
++)
5740 /* Ensure using this case. */
5742 for (av
= case_attr
->first_value
; av
; av
= av
->next
)
5744 && contained_in_p (make_numeric_value (i
), av
->value
))
5750 printf (" case %d:\n", i
);
5751 sprintf (str
, "*%s_%s_%d", unit
->name
, connection
, i
);
5752 attr
= find_attr (str
, 0);
5756 /* If single value, just write it. */
5757 value
= find_single_value (attr
);
5759 write_attr_set (attr
, 6, value
, "return", ";\n", true_rtx
, -2, -2);
5762 common_av
= find_most_used (attr
);
5763 printf (" switch (recog_memoized (insn))\n");
5766 for (av
= attr
->first_value
; av
; av
= av
->next
)
5767 if (av
!= common_av
)
5768 write_attr_case (attr
, av
, 1,
5769 "return", ";", 8, unit
->condexp
);
5771 write_attr_case (attr
, common_av
, 0,
5772 "return", ";", 8, unit
->condexp
);
5777 /* This default case should not be needed, but gcc's analysis is not
5778 good enough to realize that the default case is not needed for the
5779 second switch statement. */
5780 printf (" default:\n abort ();\n");
5781 printf (" }\n}\n\n");
5784 /* This page contains miscellaneous utility routines. */
5786 /* Given a string, return the number of comma-separated elements in it.
5787 Return 0 for the null string. */
5798 for (n
= 1; *s
; s
++)
5805 /* Given a pointer to a (char *), return a malloc'ed string containing the
5806 next comma-separated element. Advance the pointer to after the string
5807 scanned, or the end-of-string. Return NULL if at end of string. */
5810 next_comma_elt (pstr
)
5819 /* Find end of string to compute length. */
5820 for (p
= *pstr
; *p
!= ',' && *p
!= '\0'; p
++)
5823 out_str
= attr_string (*pstr
, p
- *pstr
);
5832 /* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
5833 is non-zero, build a new attribute, if one does not exist. */
5835 static struct attr_desc
*
5836 find_attr (name
, create
)
5840 struct attr_desc
*attr
;
5843 /* Before we resort to using `strcmp', see if the string address matches
5844 anywhere. In most cases, it should have been canonicalized to do so. */
5845 if (name
== alternative_name
)
5848 index
= name
[0] & (MAX_ATTRS_INDEX
- 1);
5849 for (attr
= attrs
[index
]; attr
; attr
= attr
->next
)
5850 if (name
== attr
->name
)
5853 /* Otherwise, do it the slow way. */
5854 for (attr
= attrs
[index
]; attr
; attr
= attr
->next
)
5855 if (name
[0] == attr
->name
[0] && ! strcmp (name
, attr
->name
))
5861 attr
= (struct attr_desc
*) oballoc (sizeof (struct attr_desc
));
5862 attr
->name
= attr_string (name
, strlen (name
));
5863 attr
->first_value
= attr
->default_val
= NULL
;
5864 attr
->is_numeric
= attr
->negative_ok
= attr
->is_const
= attr
->is_special
= 0;
5865 attr
->unsigned_p
= attr
->func_units_p
= attr
->blockage_p
= 0;
5866 attr
->next
= attrs
[index
];
5867 attrs
[index
] = attr
;
5872 /* Create internal attribute with the given default value. */
5875 make_internal_attr (name
, value
, special
)
5880 struct attr_desc
*attr
;
5882 attr
= find_attr (name
, 1);
5883 if (attr
->default_val
)
5886 attr
->is_numeric
= 1;
5888 attr
->is_special
= (special
& 1) != 0;
5889 attr
->negative_ok
= (special
& 2) != 0;
5890 attr
->unsigned_p
= (special
& 4) != 0;
5891 attr
->func_units_p
= (special
& 8) != 0;
5892 attr
->blockage_p
= (special
& 16) != 0;
5893 attr
->default_val
= get_attr_value (value
, attr
, -2);
5896 /* Find the most used value of an attribute. */
5898 static struct attr_value
*
5899 find_most_used (attr
)
5900 struct attr_desc
*attr
;
5902 struct attr_value
*av
;
5903 struct attr_value
*most_used
;
5909 for (av
= attr
->first_value
; av
; av
= av
->next
)
5910 if (av
->num_insns
> nuses
)
5911 nuses
= av
->num_insns
, most_used
= av
;
5916 /* If an attribute only has a single value used, return it. Otherwise
5920 find_single_value (attr
)
5921 struct attr_desc
*attr
;
5923 struct attr_value
*av
;
5926 unique_value
= NULL
;
5927 for (av
= attr
->first_value
; av
; av
= av
->next
)
5933 unique_value
= av
->value
;
5936 return unique_value
;
5939 /* Return (attr_value "n") */
5942 make_numeric_value (n
)
5945 static rtx int_values
[20];
5952 if (n
< 20 && int_values
[n
])
5953 return int_values
[n
];
5955 p
= attr_printf (MAX_DIGITS
, "%d", n
);
5956 exp
= attr_rtx (CONST_STRING
, p
);
5959 int_values
[n
] = exp
;
5965 extend_range (range
, min
, max
)
5966 struct range
*range
;
5970 if (range
->min
> min
)
5972 if (range
->max
< max
)
5977 copy_rtx_unchanging (orig
)
5985 if (RTX_UNCHANGING_P (orig
) || MEM_IN_STRUCT_P (orig
))
5988 MEM_IN_STRUCT_P (orig
) = 1;
5992 code
= GET_CODE (orig
);
6005 copy
= rtx_alloc (code
);
6006 PUT_MODE (copy
, GET_MODE (orig
));
6007 RTX_UNCHANGING_P (copy
) = 1;
6009 memcpy (&XEXP (copy
, 0), &XEXP (orig
, 0),
6010 GET_RTX_LENGTH (GET_CODE (copy
)) * sizeof (rtx
));
6015 /* Determine if an insn has a constant number of delay slots, i.e., the
6016 number of delay slots is not a function of the length of the insn. */
6019 write_const_num_delay_slots ()
6021 struct attr_desc
*attr
= find_attr ("*num_delay_slots", 0);
6022 struct attr_value
*av
;
6023 struct insn_ent
*ie
;
6027 printf ("int\nconst_num_delay_slots (insn)\n");
6028 printf (" rtx insn;\n");
6030 printf (" switch (recog_memoized (insn))\n");
6033 for (av
= attr
->first_value
; av
; av
= av
->next
)
6036 walk_attr_value (av
->value
);
6039 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
6040 if (ie
->insn_code
!= -1)
6041 printf (" case %d:\n", ie
->insn_code
);
6042 printf (" return 0;\n");
6046 printf (" default:\n");
6047 printf (" return 1;\n");
6048 printf (" }\n}\n\n");
6052 extern int main
PARAMS ((int, char **));
6060 struct attr_desc
*attr
;
6061 struct insn_def
*id
;
6065 progname
= "genattrtab";
6068 fatal ("no input file name");
6070 if (init_md_reader_args (argc
, argv
) != SUCCESS_EXIT_CODE
)
6071 return (FATAL_EXIT_CODE
);
6073 obstack_init (hash_obstack
);
6074 obstack_init (temp_obstack
);
6076 /* Set up true and false rtx's */
6077 true_rtx
= rtx_alloc (CONST_INT
);
6078 XWINT (true_rtx
, 0) = 1;
6079 false_rtx
= rtx_alloc (CONST_INT
);
6080 XWINT (false_rtx
, 0) = 0;
6081 RTX_UNCHANGING_P (true_rtx
) = RTX_UNCHANGING_P (false_rtx
) = 1;
6082 RTX_INTEGRATED_P (true_rtx
) = RTX_INTEGRATED_P (false_rtx
) = 1;
6084 alternative_name
= attr_string ("alternative", strlen ("alternative"));
6086 printf ("/* Generated automatically by the program `genattrtab'\n\
6087 from the machine description file `md'. */\n\n");
6089 /* Read the machine description. */
6095 desc
= read_md_rtx (&lineno
, &insn_code_number
);
6099 switch (GET_CODE (desc
))
6102 case DEFINE_PEEPHOLE
:
6103 case DEFINE_ASM_ATTRIBUTES
:
6104 gen_insn (desc
, lineno
);
6108 gen_attr (desc
, lineno
);
6112 gen_delay (desc
, lineno
);
6115 case DEFINE_FUNCTION_UNIT
:
6116 gen_unit (desc
, lineno
);
6122 if (GET_CODE (desc
) != DEFINE_ASM_ATTRIBUTES
)
6123 insn_index_number
++;
6127 return FATAL_EXIT_CODE
;
6131 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
6132 if (! got_define_asm_attributes
)
6134 tem
= rtx_alloc (DEFINE_ASM_ATTRIBUTES
);
6135 XVEC (tem
, 0) = rtvec_alloc (0);
6139 /* Expand DEFINE_DELAY information into new attribute. */
6143 /* Expand DEFINE_FUNCTION_UNIT information into new attributes. */
6147 printf ("#include \"config.h\"\n");
6148 printf ("#include \"system.h\"\n");
6149 printf ("#include \"rtl.h\"\n");
6150 printf ("#include \"tm_p.h\"\n");
6151 printf ("#include \"insn-config.h\"\n");
6152 printf ("#include \"recog.h\"\n");
6153 printf ("#include \"regs.h\"\n");
6154 printf ("#include \"real.h\"\n");
6155 printf ("#include \"output.h\"\n");
6156 printf ("#include \"insn-attr.h\"\n");
6157 printf ("#include \"toplev.h\"\n");
6158 printf ("#include \"flags.h\"\n");
6160 printf ("#define operands recog_data.operand\n\n");
6162 /* Make `insn_alternatives'. */
6163 insn_alternatives
= (int *) oballoc (insn_code_number
* sizeof (int));
6164 for (id
= defs
; id
; id
= id
->next
)
6165 if (id
->insn_code
>= 0)
6166 insn_alternatives
[id
->insn_code
] = (1 << id
->num_alternatives
) - 1;
6168 /* Make `insn_n_alternatives'. */
6169 insn_n_alternatives
= (int *) oballoc (insn_code_number
* sizeof (int));
6170 for (id
= defs
; id
; id
= id
->next
)
6171 if (id
->insn_code
>= 0)
6172 insn_n_alternatives
[id
->insn_code
] = id
->num_alternatives
;
6174 /* Prepare to write out attribute subroutines by checking everything stored
6175 away and building the attribute cases. */
6179 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
6180 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
6181 attr
->default_val
->value
6182 = check_attr_value (attr
->default_val
->value
, attr
);
6185 return FATAL_EXIT_CODE
;
6187 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
6188 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
6191 /* Construct extra attributes for `length'. */
6192 make_length_attrs ();
6194 /* Perform any possible optimizations to speed up compilation. */
6197 /* Now write out all the `gen_attr_...' routines. Do these before the
6198 special routines (specifically before write_function_unit_info), so
6199 that they get defined before they are used. */
6201 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
6202 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
6204 if (! attr
->is_special
&& ! attr
->is_const
)
6205 write_attr_get (attr
);
6208 /* Write out delay eligibility information, if DEFINE_DELAY present.
6209 (The function to compute the number of delay slots will be written
6213 write_eligible_delay ("delay");
6214 if (have_annul_true
)
6215 write_eligible_delay ("annul_true");
6216 if (have_annul_false
)
6217 write_eligible_delay ("annul_false");
6220 /* Write out information about function units. */
6222 write_function_unit_info ();
6224 /* Write out constant delay slot info */
6225 write_const_num_delay_slots ();
6227 write_length_unit_log ();
6230 return (ferror (stdout
) != 0 ? FATAL_EXIT_CODE
: SUCCESS_EXIT_CODE
);
6233 /* Define this so we can link with print-rtl.o to get debug_rtx function. */
6235 get_insn_name (code
)
6236 int code ATTRIBUTE_UNUSED
;