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