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, 2003, 2004, 2005 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, 51 Franklin Street, Fifth Floor, Boston, MA
21 02110-1301, USA.  */
22 
23 /* This program handles insn attributes and the DEFINE_DELAY and
24    DEFINE_INSN_RESERVATION 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_INSN_RESERVATION.  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 definitions is to create
74    arbitrarily complex expressions and have the optimization simplify them.
75 
76    Once optimization is complete, any required routines and definitions
77    will be written.
78 
79    An optimization that is not yet implemented is to hoist the constant
80    expressions entirely out of the routines and definitions that are written.
81    A way to do this is to iterate over all possible combinations of values
82    for constant attributes and generate a set of functions for that given
83    combination.  An initialization function would be written that evaluates
84    the attributes and installs the corresponding set of routines and
85    definitions (each would be accessed through a pointer).
86 
87    We use the flags in an RTX as follows:
88    `unchanging' (ATTR_IND_SIMPLIFIED_P): This rtx is fully simplified
89       independent of the insn code.
90    `in_struct' (ATTR_CURR_SIMPLIFIED_P): This rtx is fully simplified
91       for the insn code currently being processed (see optimize_attrs).
92    `return_val' (ATTR_PERMANENT_P): This rtx is permanent and unique
93       (see attr_rtx).  */
94 
95 #define ATTR_IND_SIMPLIFIED_P(RTX) (RTX_FLAG((RTX), unchanging))
96 #define ATTR_CURR_SIMPLIFIED_P(RTX) (RTX_FLAG((RTX), in_struct))
97 #define ATTR_PERMANENT_P(RTX) (RTX_FLAG((RTX), return_val))
98 
99 #if 0
100 #define strcmp_check(S1, S2) ((S1) == (S2)		\
101 			      ? 0			\
102 			      : (gcc_assert (strcmp ((S1), (S2))), 1))
103 #else
104 #define strcmp_check(S1, S2) ((S1) != (S2))
105 #endif
106 
107 #include "bconfig.h"
108 #include "system.h"
109 #include "coretypes.h"
110 #include "tm.h"
111 #include "rtl.h"
112 #include "ggc.h"
113 #include "gensupport.h"
114 
115 #ifdef HAVE_SYS_RESOURCE_H
116 # include <sys/resource.h>
117 #endif
118 
119 /* We must include obstack.h after <sys/time.h>, to avoid lossage with
120    /usr/include/sys/stdtypes.h on Sun OS 4.x.  */
121 #include "obstack.h"
122 #include "errors.h"
123 
124 #include "genattrtab.h"
125 
126 static struct obstack obstack1, obstack2;
127 struct obstack *hash_obstack = &obstack1;
128 struct obstack *temp_obstack = &obstack2;
129 
130 /* enough space to reserve for printing out ints */
131 #define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3)
132 
133 /* Define structures used to record attributes and values.  */
134 
135 /* As each DEFINE_INSN, DEFINE_PEEPHOLE, or DEFINE_ASM_ATTRIBUTES is
136    encountered, we store all the relevant information into a
137    `struct insn_def'.  This is done to allow attribute definitions to occur
138    anywhere in the file.  */
139 
140 struct insn_def
141 {
142   struct insn_def *next;	/* Next insn in chain.  */
143   rtx def;			/* The DEFINE_...  */
144   int insn_code;		/* Instruction number.  */
145   int insn_index;		/* Expression numer in file, for errors.  */
146   int lineno;			/* Line number.  */
147   int num_alternatives;		/* Number of alternatives.  */
148   int vec_idx;			/* Index of attribute vector in `def'.  */
149 };
150 
151 /* Once everything has been read in, we store in each attribute value a list
152    of insn codes that have that value.  Here is the structure used for the
153    list.  */
154 
155 struct insn_ent
156 {
157   struct insn_ent *next;	/* Next in chain.  */
158   struct insn_def *def;		/* Instruction definition.  */
159 };
160 
161 /* Each value of an attribute (either constant or computed) is assigned a
162    structure which is used as the listhead of the insns that have that
163    value.  */
164 
165 struct attr_value
166 {
167   rtx value;			/* Value of attribute.  */
168   struct attr_value *next;	/* Next attribute value in chain.  */
169   struct insn_ent *first_insn;	/* First insn with this value.  */
170   int num_insns;		/* Number of insns with this value.  */
171   int has_asm_insn;		/* True if this value used for `asm' insns */
172 };
173 
174 /* Structure for each attribute.  */
175 
176 struct attr_desc
177 {
178   char *name;			/* Name of attribute.  */
179   struct attr_desc *next;	/* Next attribute.  */
180   struct attr_value *first_value; /* First value of this attribute.  */
181   struct attr_value *default_val; /* Default value for this attribute.  */
182   int lineno : 24;		/* Line number.  */
183   unsigned is_numeric	: 1;	/* Values of this attribute are numeric.  */
184   unsigned is_const	: 1;	/* Attribute value constant for each run.  */
185   unsigned is_special	: 1;	/* Don't call `write_attr_set'.  */
186   unsigned static_p	: 1;	/* Make the output function static.  */
187 };
188 
189 /* Structure for each DEFINE_DELAY.  */
190 
191 struct delay_desc
192 {
193   rtx def;			/* DEFINE_DELAY expression.  */
194   struct delay_desc *next;	/* Next DEFINE_DELAY.  */
195   int num;			/* Number of DEFINE_DELAY, starting at 1.  */
196   int lineno;			/* Line number.  */
197 };
198 
199 /* Listheads of above structures.  */
200 
201 /* This one is indexed by the first character of the attribute name.  */
202 #define MAX_ATTRS_INDEX 256
203 static struct attr_desc *attrs[MAX_ATTRS_INDEX];
204 static struct insn_def *defs;
205 static struct delay_desc *delays;
206 
207 /* Other variables.  */
208 
209 static int insn_code_number;
210 static int insn_index_number;
211 static int got_define_asm_attributes;
212 static int must_extract;
213 static int must_constrain;
214 static int address_used;
215 static int length_used;
216 static int num_delays;
217 static int have_annul_true, have_annul_false;
218 static int num_insn_ents;
219 
220 int num_dfa_decls;
221 
222 /* Stores, for each insn code, the number of constraint alternatives.  */
223 
224 static int *insn_n_alternatives;
225 
226 /* Stores, for each insn code, a bitmap that has bits on for each possible
227    alternative.  */
228 
229 static int *insn_alternatives;
230 
231 /* Used to simplify expressions.  */
232 
233 static rtx true_rtx, false_rtx;
234 
235 /* Used to reduce calls to `strcmp' */
236 
237 static const char *alternative_name;
238 static const char *length_str;
239 static const char *delay_type_str;
240 static const char *delay_1_0_str;
241 static const char *num_delay_slots_str;
242 
243 /* Indicate that REG_DEAD notes are valid if dead_or_set_p is ever
244    called.  */
245 
246 int reload_completed = 0;
247 
248 /* Some machines test `optimize' in macros called from rtlanal.c, so we need
249    to define it here.  */
250 
251 int optimize = 0;
252 
253 /* Simplify an expression.  Only call the routine if there is something to
254    simplify.  */
255 #define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX)	\
256   (ATTR_IND_SIMPLIFIED_P (EXP) || ATTR_CURR_SIMPLIFIED_P (EXP) ? (EXP)	\
257    : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
258 
259 #define DEF_ATTR_STRING(S) (attr_string ((S), strlen (S)))
260 
261 /* These are referenced by rtlanal.c and hence need to be defined somewhere.
262    They won't actually be used.  */
263 
264 rtx global_rtl[GR_MAX];
265 rtx pic_offset_table_rtx;
266 
267 static void attr_hash_add_rtx	(int, rtx);
268 static void attr_hash_add_string (int, char *);
269 static rtx attr_rtx		(enum rtx_code, ...);
270 static rtx attr_rtx_1		(enum rtx_code, va_list);
271 static char *attr_string        (const char *, int);
272 static rtx check_attr_value	(rtx, struct attr_desc *);
273 static rtx convert_set_attr_alternative (rtx, struct insn_def *);
274 static rtx convert_set_attr	(rtx, struct insn_def *);
275 static void check_defs		(void);
276 static rtx make_canonical	(struct attr_desc *, rtx);
277 static struct attr_value *get_attr_value (rtx, struct attr_desc *, int);
278 static rtx copy_rtx_unchanging	(rtx);
279 static rtx copy_boolean		(rtx);
280 static void expand_delays	(void);
281 static void fill_attr		(struct attr_desc *);
282 static rtx substitute_address	(rtx, rtx (*) (rtx), rtx (*) (rtx));
283 static void make_length_attrs	(void);
284 static rtx identity_fn		(rtx);
285 static rtx zero_fn		(rtx);
286 static rtx one_fn		(rtx);
287 static rtx max_fn		(rtx);
288 static rtx min_fn		(rtx);
289 static void write_length_unit_log (void);
290 static rtx simplify_cond	(rtx, int, int);
291 static void clear_struct_flag (rtx);
292 static void remove_insn_ent  (struct attr_value *, struct insn_ent *);
293 static void insert_insn_ent  (struct attr_value *, struct insn_ent *);
294 static rtx insert_right_side	(enum rtx_code, rtx, rtx, int, int);
295 static rtx make_alternative_compare (int);
296 static int compute_alternative_mask (rtx, enum rtx_code);
297 static rtx evaluate_eq_attr	(rtx, rtx, int, int);
298 static rtx simplify_and_tree	(rtx, rtx *, int, int);
299 static rtx simplify_or_tree	(rtx, rtx *, int, int);
300 static rtx simplify_test_exp	(rtx, int, int);
301 static rtx simplify_test_exp_in_temp (rtx, int, int);
302 static void optimize_attrs	(void);
303 static void gen_attr		(rtx, int);
304 static int count_alternatives	(rtx);
305 static int compares_alternatives_p (rtx);
306 static int contained_in_p	(rtx, rtx);
307 static void gen_insn		(rtx, int);
308 static void gen_delay		(rtx, int);
309 static void write_test_expr	(rtx, int);
310 static int max_attr_value	(rtx, int*);
311 static int min_attr_value	(rtx, int*);
312 static int or_attr_value	(rtx, int*);
313 static void walk_attr_value	(rtx);
314 static void write_attr_get	(struct attr_desc *);
315 static rtx eliminate_known_true (rtx, rtx, int, int);
316 static void write_attr_set	(struct attr_desc *, int, rtx,
317 				 const char *, const char *, rtx,
318 				 int, int);
319 static void write_insn_cases	(struct insn_ent *, int);
320 static void write_attr_case	(struct attr_desc *, struct attr_value *,
321 				 int, const char *, const char *, int, rtx);
322 static void write_attr_valueq	(struct attr_desc *, const char *);
323 static void write_attr_value	(struct attr_desc *, rtx);
324 static void write_upcase	(const char *);
325 static void write_indent	(int);
326 static void write_eligible_delay (const char *);
327 static int write_expr_attr_cache (rtx, struct attr_desc *);
328 static void write_const_num_delay_slots (void);
329 static char *next_comma_elt	(const char **);
330 static struct attr_desc *find_attr (const char **, int);
331 static struct attr_value *find_most_used  (struct attr_desc *);
332 static rtx attr_eq		(const char *, const char *);
333 static const char *attr_numeral	(int);
334 static int attr_equal_p		(rtx, rtx);
335 static rtx attr_copy_rtx	(rtx);
336 static int attr_rtx_cost	(rtx);
337 static bool attr_alt_subset_p (rtx, rtx);
338 static bool attr_alt_subset_of_compl_p (rtx, rtx);
339 static rtx attr_alt_intersection (rtx, rtx);
340 static rtx attr_alt_union (rtx, rtx);
341 static rtx attr_alt_complement (rtx);
342 static rtx mk_attr_alt (int);
343 
344 #define oballoc(size) obstack_alloc (hash_obstack, size)
345 
346 /* Hash table for sharing RTL and strings.  */
347 
348 /* Each hash table slot is a bucket containing a chain of these structures.
349    Strings are given negative hash codes; RTL expressions are given positive
350    hash codes.  */
351 
352 struct attr_hash
353 {
354   struct attr_hash *next;	/* Next structure in the bucket.  */
355   int hashcode;			/* Hash code of this rtx or string.  */
356   union
357     {
358       char *str;		/* The string (negative hash codes) */
359       rtx rtl;			/* or the RTL recorded here.  */
360     } u;
361 };
362 
363 /* Now here is the hash table.  When recording an RTL, it is added to
364    the slot whose index is the hash code mod the table size.  Note
365    that the hash table is used for several kinds of RTL (see attr_rtx)
366    and for strings.  While all these live in the same table, they are
367    completely independent, and the hash code is computed differently
368    for each.  */
369 
370 #define RTL_HASH_SIZE 4093
371 struct attr_hash *attr_hash_table[RTL_HASH_SIZE];
372 
373 /* Here is how primitive or already-shared RTL's hash
374    codes are made.  */
375 #define RTL_HASH(RTL) ((long) (RTL) & 0777777)
376 
377 /* Add an entry to the hash table for RTL with hash code HASHCODE.  */
378 
379 static void
attr_hash_add_rtx(int hashcode,rtx rtl)380 attr_hash_add_rtx (int hashcode, rtx rtl)
381 {
382   struct attr_hash *h;
383 
384   h = obstack_alloc (hash_obstack, sizeof (struct attr_hash));
385   h->hashcode = hashcode;
386   h->u.rtl = rtl;
387   h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
388   attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
389 }
390 
391 /* Add an entry to the hash table for STRING with hash code HASHCODE.  */
392 
393 static void
attr_hash_add_string(int hashcode,char * str)394 attr_hash_add_string (int hashcode, char *str)
395 {
396   struct attr_hash *h;
397 
398   h = obstack_alloc (hash_obstack, sizeof (struct attr_hash));
399   h->hashcode = -hashcode;
400   h->u.str = str;
401   h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
402   attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
403 }
404 
405 /* Generate an RTL expression, but avoid duplicates.
406    Set the ATTR_PERMANENT_P flag for these permanent objects.
407 
408    In some cases we cannot uniquify; then we return an ordinary
409    impermanent rtx with ATTR_PERMANENT_P clear.
410 
411    Args are as follows:
412 
413    rtx attr_rtx (code, [element1, ..., elementn])  */
414 
415 static rtx
attr_rtx_1(enum rtx_code code,va_list p)416 attr_rtx_1 (enum rtx_code code, va_list p)
417 {
418   rtx rt_val = NULL_RTX;/* RTX to return to caller...		*/
419   int hashcode;
420   struct attr_hash *h;
421   struct obstack *old_obstack = rtl_obstack;
422 
423   /* For each of several cases, search the hash table for an existing entry.
424      Use that entry if one is found; otherwise create a new RTL and add it
425      to the table.  */
426 
427   if (GET_RTX_CLASS (code) == RTX_UNARY)
428     {
429       rtx arg0 = va_arg (p, rtx);
430 
431       /* A permanent object cannot point to impermanent ones.  */
432       if (! ATTR_PERMANENT_P (arg0))
433 	{
434 	  rt_val = rtx_alloc (code);
435 	  XEXP (rt_val, 0) = arg0;
436 	  return rt_val;
437 	}
438 
439       hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
440       for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
441 	if (h->hashcode == hashcode
442 	    && GET_CODE (h->u.rtl) == code
443 	    && XEXP (h->u.rtl, 0) == arg0)
444 	  return h->u.rtl;
445 
446       if (h == 0)
447 	{
448 	  rtl_obstack = hash_obstack;
449 	  rt_val = rtx_alloc (code);
450 	  XEXP (rt_val, 0) = arg0;
451 	}
452     }
453   else if (GET_RTX_CLASS (code) == RTX_BIN_ARITH
454   	   || GET_RTX_CLASS (code) == RTX_COMM_ARITH
455   	   || GET_RTX_CLASS (code) == RTX_COMPARE
456   	   || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
457     {
458       rtx arg0 = va_arg (p, rtx);
459       rtx arg1 = va_arg (p, rtx);
460 
461       /* A permanent object cannot point to impermanent ones.  */
462       if (! ATTR_PERMANENT_P (arg0) || ! ATTR_PERMANENT_P (arg1))
463 	{
464 	  rt_val = rtx_alloc (code);
465 	  XEXP (rt_val, 0) = arg0;
466 	  XEXP (rt_val, 1) = arg1;
467 	  return rt_val;
468 	}
469 
470       hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
471       for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
472 	if (h->hashcode == hashcode
473 	    && GET_CODE (h->u.rtl) == code
474 	    && XEXP (h->u.rtl, 0) == arg0
475 	    && XEXP (h->u.rtl, 1) == arg1)
476 	  return h->u.rtl;
477 
478       if (h == 0)
479 	{
480 	  rtl_obstack = hash_obstack;
481 	  rt_val = rtx_alloc (code);
482 	  XEXP (rt_val, 0) = arg0;
483 	  XEXP (rt_val, 1) = arg1;
484 	}
485     }
486   else if (GET_RTX_LENGTH (code) == 1
487 	   && GET_RTX_FORMAT (code)[0] == 's')
488     {
489       char *arg0 = va_arg (p, char *);
490 
491       arg0 = DEF_ATTR_STRING (arg0);
492 
493       hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
494       for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
495 	if (h->hashcode == hashcode
496 	    && GET_CODE (h->u.rtl) == code
497 	    && XSTR (h->u.rtl, 0) == arg0)
498 	  return h->u.rtl;
499 
500       if (h == 0)
501 	{
502 	  rtl_obstack = hash_obstack;
503 	  rt_val = rtx_alloc (code);
504 	  XSTR (rt_val, 0) = arg0;
505 	}
506     }
507   else if (GET_RTX_LENGTH (code) == 2
508 	   && GET_RTX_FORMAT (code)[0] == 's'
509 	   && GET_RTX_FORMAT (code)[1] == 's')
510     {
511       char *arg0 = va_arg (p, char *);
512       char *arg1 = va_arg (p, char *);
513 
514       hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
515       for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
516 	if (h->hashcode == hashcode
517 	    && GET_CODE (h->u.rtl) == code
518 	    && XSTR (h->u.rtl, 0) == arg0
519 	    && XSTR (h->u.rtl, 1) == arg1)
520 	  return h->u.rtl;
521 
522       if (h == 0)
523 	{
524 	  rtl_obstack = hash_obstack;
525 	  rt_val = rtx_alloc (code);
526 	  XSTR (rt_val, 0) = arg0;
527 	  XSTR (rt_val, 1) = arg1;
528 	}
529     }
530   else if (code == CONST_INT)
531     {
532       HOST_WIDE_INT arg0 = va_arg (p, HOST_WIDE_INT);
533       if (arg0 == 0)
534 	return false_rtx;
535       else if (arg0 == 1)
536 	return true_rtx;
537       else
538 	goto nohash;
539     }
540   else
541     {
542       int i;		/* Array indices...			*/
543       const char *fmt;	/* Current rtx's format...		*/
544     nohash:
545       rt_val = rtx_alloc (code);	/* Allocate the storage space.  */
546 
547       fmt = GET_RTX_FORMAT (code);	/* Find the right format...  */
548       for (i = 0; i < GET_RTX_LENGTH (code); i++)
549 	{
550 	  switch (*fmt++)
551 	    {
552 	    case '0':		/* Unused field.  */
553 	      break;
554 
555 	    case 'i':		/* An integer?  */
556 	      XINT (rt_val, i) = va_arg (p, int);
557 	      break;
558 
559 	    case 'w':		/* A wide integer? */
560 	      XWINT (rt_val, i) = va_arg (p, HOST_WIDE_INT);
561 	      break;
562 
563 	    case 's':		/* A string?  */
564 	      XSTR (rt_val, i) = va_arg (p, char *);
565 	      break;
566 
567 	    case 'e':		/* An expression?  */
568 	    case 'u':		/* An insn?  Same except when printing.  */
569 	      XEXP (rt_val, i) = va_arg (p, rtx);
570 	      break;
571 
572 	    case 'E':		/* An RTX vector?  */
573 	      XVEC (rt_val, i) = va_arg (p, rtvec);
574 	      break;
575 
576 	    default:
577 	      gcc_unreachable ();
578 	    }
579 	}
580       return rt_val;
581     }
582 
583   rtl_obstack = old_obstack;
584   attr_hash_add_rtx (hashcode, rt_val);
585   ATTR_PERMANENT_P (rt_val) = 1;
586   return rt_val;
587 }
588 
589 static rtx
attr_rtx(enum rtx_code code,...)590 attr_rtx (enum rtx_code code, ...)
591 {
592   rtx result;
593   va_list p;
594 
595   va_start (p, code);
596   result = attr_rtx_1 (code, p);
597   va_end (p);
598   return result;
599 }
600 
601 /* Create a new string printed with the printf line arguments into a space
602    of at most LEN bytes:
603 
604    rtx attr_printf (len, format, [arg1, ..., argn])  */
605 
606 char *
attr_printf(unsigned int len,const char * fmt,...)607 attr_printf (unsigned int len, const char *fmt, ...)
608 {
609   char str[256];
610   va_list p;
611 
612   va_start (p, fmt);
613 
614   gcc_assert (len < sizeof str); /* Leave room for \0.  */
615 
616   vsprintf (str, fmt, p);
617   va_end (p);
618 
619   return DEF_ATTR_STRING (str);
620 }
621 
622 static rtx
attr_eq(const char * name,const char * value)623 attr_eq (const char *name, const char *value)
624 {
625   return attr_rtx (EQ_ATTR, DEF_ATTR_STRING (name), DEF_ATTR_STRING (value));
626 }
627 
628 static const char *
attr_numeral(int n)629 attr_numeral (int n)
630 {
631   return XSTR (make_numeric_value (n), 0);
632 }
633 
634 /* Return a permanent (possibly shared) copy of a string STR (not assumed
635    to be null terminated) with LEN bytes.  */
636 
637 static char *
attr_string(const char * str,int len)638 attr_string (const char *str, int len)
639 {
640   struct attr_hash *h;
641   int hashcode;
642   int i;
643   char *new_str;
644 
645   /* Compute the hash code.  */
646   hashcode = (len + 1) * 613 + (unsigned) str[0];
647   for (i = 1; i <= len; i += 2)
648     hashcode = ((hashcode * 613) + (unsigned) str[i]);
649   if (hashcode < 0)
650     hashcode = -hashcode;
651 
652   /* Search the table for the string.  */
653   for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
654     if (h->hashcode == -hashcode && h->u.str[0] == str[0]
655 	&& !strncmp (h->u.str, str, len))
656       return h->u.str;			/* <-- return if found.  */
657 
658   /* Not found; create a permanent copy and add it to the hash table.  */
659   new_str = obstack_alloc (hash_obstack, len + 1);
660   memcpy (new_str, str, len);
661   new_str[len] = '\0';
662   attr_hash_add_string (hashcode, new_str);
663 
664   return new_str;			/* Return the new string.  */
665 }
666 
667 /* Check two rtx's for equality of contents,
668    taking advantage of the fact that if both are hashed
669    then they can't be equal unless they are the same object.  */
670 
671 static int
attr_equal_p(rtx x,rtx y)672 attr_equal_p (rtx x, rtx y)
673 {
674   return (x == y || (! (ATTR_PERMANENT_P (x) && ATTR_PERMANENT_P (y))
675 		     && rtx_equal_p (x, y)));
676 }
677 
678 /* Copy an attribute value expression,
679    descending to all depths, but not copying any
680    permanent hashed subexpressions.  */
681 
682 static rtx
attr_copy_rtx(rtx orig)683 attr_copy_rtx (rtx orig)
684 {
685   rtx copy;
686   int i, j;
687   RTX_CODE code;
688   const char *format_ptr;
689 
690   /* No need to copy a permanent object.  */
691   if (ATTR_PERMANENT_P (orig))
692     return orig;
693 
694   code = GET_CODE (orig);
695 
696   switch (code)
697     {
698     case REG:
699     case CONST_INT:
700     case CONST_DOUBLE:
701     case CONST_VECTOR:
702     case SYMBOL_REF:
703     case CODE_LABEL:
704     case PC:
705     case CC0:
706       return orig;
707 
708     default:
709       break;
710     }
711 
712   copy = rtx_alloc (code);
713   PUT_MODE (copy, GET_MODE (orig));
714   ATTR_IND_SIMPLIFIED_P (copy) = ATTR_IND_SIMPLIFIED_P (orig);
715   ATTR_CURR_SIMPLIFIED_P (copy) = ATTR_CURR_SIMPLIFIED_P (orig);
716   ATTR_PERMANENT_P (copy) = ATTR_PERMANENT_P (orig);
717 
718   format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
719 
720   for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
721     {
722       switch (*format_ptr++)
723 	{
724 	case 'e':
725 	  XEXP (copy, i) = XEXP (orig, i);
726 	  if (XEXP (orig, i) != NULL)
727 	    XEXP (copy, i) = attr_copy_rtx (XEXP (orig, i));
728 	  break;
729 
730 	case 'E':
731 	case 'V':
732 	  XVEC (copy, i) = XVEC (orig, i);
733 	  if (XVEC (orig, i) != NULL)
734 	    {
735 	      XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
736 	      for (j = 0; j < XVECLEN (copy, i); j++)
737 		XVECEXP (copy, i, j) = attr_copy_rtx (XVECEXP (orig, i, j));
738 	    }
739 	  break;
740 
741 	case 'n':
742 	case 'i':
743 	  XINT (copy, i) = XINT (orig, i);
744 	  break;
745 
746 	case 'w':
747 	  XWINT (copy, i) = XWINT (orig, i);
748 	  break;
749 
750 	case 's':
751 	case 'S':
752 	  XSTR (copy, i) = XSTR (orig, i);
753 	  break;
754 
755 	default:
756 	  gcc_unreachable ();
757 	}
758     }
759   return copy;
760 }
761 
762 /* Given a test expression for an attribute, ensure it is validly formed.
763    IS_CONST indicates whether the expression is constant for each compiler
764    run (a constant expression may not test any particular insn).
765 
766    Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
767    and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")).  Do the latter
768    test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
769 
770    Update the string address in EQ_ATTR expression to be the same used
771    in the attribute (or `alternative_name') to speed up subsequent
772    `find_attr' calls and eliminate most `strcmp' calls.
773 
774    Return the new expression, if any.  */
775 
776 rtx
check_attr_test(rtx exp,int is_const,int lineno)777 check_attr_test (rtx exp, int is_const, int lineno)
778 {
779   struct attr_desc *attr;
780   struct attr_value *av;
781   const char *name_ptr, *p;
782   rtx orexp, newexp;
783 
784   switch (GET_CODE (exp))
785     {
786     case EQ_ATTR:
787       /* Handle negation test.  */
788       if (XSTR (exp, 1)[0] == '!')
789 	return check_attr_test (attr_rtx (NOT,
790 					  attr_eq (XSTR (exp, 0),
791 						   &XSTR (exp, 1)[1])),
792 				is_const, lineno);
793 
794       else if (n_comma_elts (XSTR (exp, 1)) == 1)
795 	{
796 	  attr = find_attr (&XSTR (exp, 0), 0);
797 	  if (attr == NULL)
798 	    {
799 	      if (! strcmp (XSTR (exp, 0), "alternative"))
800 		return mk_attr_alt (1 << atoi (XSTR (exp, 1)));
801 	      else
802 		fatal ("unknown attribute `%s' in EQ_ATTR", XSTR (exp, 0));
803 	    }
804 
805 	  if (is_const && ! attr->is_const)
806 	    fatal ("constant expression uses insn attribute `%s' in EQ_ATTR",
807 		   XSTR (exp, 0));
808 
809 	  /* Copy this just to make it permanent,
810 	     so expressions using it can be permanent too.  */
811 	  exp = attr_eq (XSTR (exp, 0), XSTR (exp, 1));
812 
813 	  /* It shouldn't be possible to simplify the value given to a
814 	     constant attribute, so don't expand this until it's time to
815 	     write the test expression.  */
816 	  if (attr->is_const)
817 	    ATTR_IND_SIMPLIFIED_P (exp) = 1;
818 
819 	  if (attr->is_numeric)
820 	    {
821 	      for (p = XSTR (exp, 1); *p; p++)
822 		if (! ISDIGIT (*p))
823 		  fatal ("attribute `%s' takes only numeric values",
824 			 XSTR (exp, 0));
825 	    }
826 	  else
827 	    {
828 	      for (av = attr->first_value; av; av = av->next)
829 		if (GET_CODE (av->value) == CONST_STRING
830 		    && ! strcmp (XSTR (exp, 1), XSTR (av->value, 0)))
831 		  break;
832 
833 	      if (av == NULL)
834 		fatal ("unknown value `%s' for `%s' attribute",
835 		       XSTR (exp, 1), XSTR (exp, 0));
836 	    }
837 	}
838       else
839 	{
840 	  if (! strcmp (XSTR (exp, 0), "alternative"))
841 	    {
842 	      int set = 0;
843 
844 	      name_ptr = XSTR (exp, 1);
845 	      while ((p = next_comma_elt (&name_ptr)) != NULL)
846 		set |= 1 << atoi (p);
847 
848 	      return mk_attr_alt (set);
849 	    }
850 	  else
851 	    {
852 	      /* Make an IOR tree of the possible values.  */
853 	      orexp = false_rtx;
854 	      name_ptr = XSTR (exp, 1);
855 	      while ((p = next_comma_elt (&name_ptr)) != NULL)
856 		{
857 		  newexp = attr_eq (XSTR (exp, 0), p);
858 		  orexp = insert_right_side (IOR, orexp, newexp, -2, -2);
859 		}
860 
861 	      return check_attr_test (orexp, is_const, lineno);
862 	    }
863 	}
864       break;
865 
866     case ATTR_FLAG:
867       break;
868 
869     case CONST_INT:
870       /* Either TRUE or FALSE.  */
871       if (XWINT (exp, 0))
872 	return true_rtx;
873       else
874 	return false_rtx;
875 
876     case IOR:
877     case AND:
878       XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const, lineno);
879       XEXP (exp, 1) = check_attr_test (XEXP (exp, 1), is_const, lineno);
880       break;
881 
882     case NOT:
883       XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const, lineno);
884       break;
885 
886     case MATCH_OPERAND:
887       if (is_const)
888 	fatal ("RTL operator \"%s\" not valid in constant attribute test",
889 	       GET_RTX_NAME (GET_CODE (exp)));
890       /* These cases can't be simplified.  */
891       ATTR_IND_SIMPLIFIED_P (exp) = 1;
892       break;
893 
894     case LE:  case LT:  case GT:  case GE:
895     case LEU: case LTU: case GTU: case GEU:
896     case NE:  case EQ:
897       if (GET_CODE (XEXP (exp, 0)) == SYMBOL_REF
898 	  && GET_CODE (XEXP (exp, 1)) == SYMBOL_REF)
899 	exp = attr_rtx (GET_CODE (exp),
900 			attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 0), 0)),
901 			attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 1), 0)));
902       /* These cases can't be simplified.  */
903       ATTR_IND_SIMPLIFIED_P (exp) = 1;
904       break;
905 
906     case SYMBOL_REF:
907       if (is_const)
908 	{
909 	  /* These cases are valid for constant attributes, but can't be
910 	     simplified.  */
911 	  exp = attr_rtx (SYMBOL_REF, XSTR (exp, 0));
912 	  ATTR_IND_SIMPLIFIED_P (exp) = 1;
913 	  break;
914 	}
915     default:
916       fatal ("RTL operator \"%s\" not valid in attribute test",
917 	     GET_RTX_NAME (GET_CODE (exp)));
918     }
919 
920   return exp;
921 }
922 
923 /* Given an expression, ensure that it is validly formed and that all named
924    attribute values are valid for the given attribute.  Issue a fatal error
925    if not.  If no attribute is specified, assume a numeric attribute.
926 
927    Return a perhaps modified replacement expression for the value.  */
928 
929 static rtx
check_attr_value(rtx exp,struct attr_desc * attr)930 check_attr_value (rtx exp, struct attr_desc *attr)
931 {
932   struct attr_value *av;
933   const char *p;
934   int i;
935 
936   switch (GET_CODE (exp))
937     {
938     case CONST_INT:
939       if (attr && ! attr->is_numeric)
940 	{
941 	  message_with_line (attr->lineno,
942 			     "CONST_INT not valid for non-numeric attribute %s",
943 			     attr->name);
944 	  have_error = 1;
945 	  break;
946 	}
947 
948       if (INTVAL (exp) < 0)
949 	{
950 	  message_with_line (attr->lineno,
951 			     "negative numeric value specified for attribute %s",
952 			     attr->name);
953 	  have_error = 1;
954 	  break;
955 	}
956       break;
957 
958     case CONST_STRING:
959       if (! strcmp (XSTR (exp, 0), "*"))
960 	break;
961 
962       if (attr == 0 || attr->is_numeric)
963 	{
964 	  p = XSTR (exp, 0);
965 	  for (; *p; p++)
966 	    if (! ISDIGIT (*p))
967 	      {
968 		message_with_line (attr ? attr->lineno : 0,
969 				   "non-numeric value for numeric attribute %s",
970 				   attr ? attr->name : "internal");
971 		have_error = 1;
972 		break;
973 	      }
974 	  break;
975 	}
976 
977       for (av = attr->first_value; av; av = av->next)
978 	if (GET_CODE (av->value) == CONST_STRING
979 	    && ! strcmp (XSTR (av->value, 0), XSTR (exp, 0)))
980 	  break;
981 
982       if (av == NULL)
983 	{
984 	  message_with_line (attr->lineno,
985 			     "unknown value `%s' for `%s' attribute",
986 			     XSTR (exp, 0), attr ? attr->name : "internal");
987 	  have_error = 1;
988 	}
989       break;
990 
991     case IF_THEN_ELSE:
992       XEXP (exp, 0) = check_attr_test (XEXP (exp, 0),
993 				       attr ? attr->is_const : 0,
994 				       attr ? attr->lineno : 0);
995       XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
996       XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
997       break;
998 
999     case PLUS:
1000     case MINUS:
1001     case MULT:
1002     case DIV:
1003     case MOD:
1004       if (attr && !attr->is_numeric)
1005 	{
1006 	  message_with_line (attr->lineno,
1007 			     "invalid operation `%s' for non-numeric attribute value",
1008 			     GET_RTX_NAME (GET_CODE (exp)));
1009 	  have_error = 1;
1010 	  break;
1011 	}
1012       /* Fall through.  */
1013 
1014     case IOR:
1015     case AND:
1016       XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
1017       XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1018       break;
1019 
1020     case FFS:
1021     case CLZ:
1022     case CTZ:
1023     case POPCOUNT:
1024     case PARITY:
1025       XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
1026       break;
1027 
1028     case COND:
1029       if (XVECLEN (exp, 0) % 2 != 0)
1030 	{
1031 	  message_with_line (attr->lineno,
1032 			     "first operand of COND must have even length");
1033 	  have_error = 1;
1034 	  break;
1035 	}
1036 
1037       for (i = 0; i < XVECLEN (exp, 0); i += 2)
1038 	{
1039 	  XVECEXP (exp, 0, i) = check_attr_test (XVECEXP (exp, 0, i),
1040 						 attr ? attr->is_const : 0,
1041 						 attr ? attr->lineno : 0);
1042 	  XVECEXP (exp, 0, i + 1)
1043 	    = check_attr_value (XVECEXP (exp, 0, i + 1), attr);
1044 	}
1045 
1046       XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1047       break;
1048 
1049     case ATTR:
1050       {
1051 	struct attr_desc *attr2 = find_attr (&XSTR (exp, 0), 0);
1052 	if (attr2 == NULL)
1053 	  {
1054 	    message_with_line (attr ? attr->lineno : 0,
1055 			       "unknown attribute `%s' in ATTR",
1056 			       XSTR (exp, 0));
1057 	    have_error = 1;
1058 	  }
1059 	else if (attr && attr->is_const && ! attr2->is_const)
1060 	  {
1061 	    message_with_line (attr->lineno,
1062 		"non-constant attribute `%s' referenced from `%s'",
1063 		XSTR (exp, 0), attr->name);
1064 	    have_error = 1;
1065 	  }
1066 	else if (attr
1067 		 && attr->is_numeric != attr2->is_numeric)
1068 	  {
1069 	    message_with_line (attr->lineno,
1070 		"numeric attribute mismatch calling `%s' from `%s'",
1071 		XSTR (exp, 0), attr->name);
1072 	    have_error = 1;
1073 	  }
1074       }
1075       break;
1076 
1077     case SYMBOL_REF:
1078       /* A constant SYMBOL_REF is valid as a constant attribute test and
1079          is expanded later by make_canonical into a COND.  In a non-constant
1080          attribute test, it is left be.  */
1081       return attr_rtx (SYMBOL_REF, XSTR (exp, 0));
1082 
1083     default:
1084       message_with_line (attr ? attr->lineno : 0,
1085 			 "invalid operation `%s' for attribute value",
1086 			 GET_RTX_NAME (GET_CODE (exp)));
1087       have_error = 1;
1088       break;
1089     }
1090 
1091   return exp;
1092 }
1093 
1094 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
1095    It becomes a COND with each test being (eq_attr "alternative" "n") */
1096 
1097 static rtx
convert_set_attr_alternative(rtx exp,struct insn_def * id)1098 convert_set_attr_alternative (rtx exp, struct insn_def *id)
1099 {
1100   int num_alt = id->num_alternatives;
1101   rtx condexp;
1102   int i;
1103 
1104   if (XVECLEN (exp, 1) != num_alt)
1105     {
1106       message_with_line (id->lineno,
1107 			 "bad number of entries in SET_ATTR_ALTERNATIVE");
1108       have_error = 1;
1109       return NULL_RTX;
1110     }
1111 
1112   /* Make a COND with all tests but the last.  Select the last value via the
1113      default.  */
1114   condexp = rtx_alloc (COND);
1115   XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);
1116 
1117   for (i = 0; i < num_alt - 1; i++)
1118     {
1119       const char *p;
1120       p = attr_numeral (i);
1121 
1122       XVECEXP (condexp, 0, 2 * i) = attr_eq (alternative_name, p);
1123       XVECEXP (condexp, 0, 2 * i + 1) = XVECEXP (exp, 1, i);
1124     }
1125 
1126   XEXP (condexp, 1) = XVECEXP (exp, 1, i);
1127 
1128   return attr_rtx (SET, attr_rtx (ATTR, XSTR (exp, 0)), condexp);
1129 }
1130 
1131 /* Given a SET_ATTR, convert to the appropriate SET.  If a comma-separated
1132    list of values is given, convert to SET_ATTR_ALTERNATIVE first.  */
1133 
1134 static rtx
convert_set_attr(rtx exp,struct insn_def * id)1135 convert_set_attr (rtx exp, struct insn_def *id)
1136 {
1137   rtx newexp;
1138   const char *name_ptr;
1139   char *p;
1140   int n;
1141 
1142   /* See how many alternative specified.  */
1143   n = n_comma_elts (XSTR (exp, 1));
1144   if (n == 1)
1145     return attr_rtx (SET,
1146 		     attr_rtx (ATTR, XSTR (exp, 0)),
1147 		     attr_rtx (CONST_STRING, XSTR (exp, 1)));
1148 
1149   newexp = rtx_alloc (SET_ATTR_ALTERNATIVE);
1150   XSTR (newexp, 0) = XSTR (exp, 0);
1151   XVEC (newexp, 1) = rtvec_alloc (n);
1152 
1153   /* Process each comma-separated name.  */
1154   name_ptr = XSTR (exp, 1);
1155   n = 0;
1156   while ((p = next_comma_elt (&name_ptr)) != NULL)
1157     XVECEXP (newexp, 1, n++) = attr_rtx (CONST_STRING, p);
1158 
1159   return convert_set_attr_alternative (newexp, id);
1160 }
1161 
1162 /* Scan all definitions, checking for validity.  Also, convert any SET_ATTR
1163    and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
1164    expressions.  */
1165 
1166 static void
check_defs(void)1167 check_defs (void)
1168 {
1169   struct insn_def *id;
1170   struct attr_desc *attr;
1171   int i;
1172   rtx value;
1173 
1174   for (id = defs; id; id = id->next)
1175     {
1176       if (XVEC (id->def, id->vec_idx) == NULL)
1177 	continue;
1178 
1179       for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1180 	{
1181 	  value = XVECEXP (id->def, id->vec_idx, i);
1182 	  switch (GET_CODE (value))
1183 	    {
1184 	    case SET:
1185 	      if (GET_CODE (XEXP (value, 0)) != ATTR)
1186 		{
1187 		  message_with_line (id->lineno, "bad attribute set");
1188 		  have_error = 1;
1189 		  value = NULL_RTX;
1190 		}
1191 	      break;
1192 
1193 	    case SET_ATTR_ALTERNATIVE:
1194 	      value = convert_set_attr_alternative (value, id);
1195 	      break;
1196 
1197 	    case SET_ATTR:
1198 	      value = convert_set_attr (value, id);
1199 	      break;
1200 
1201 	    default:
1202 	      message_with_line (id->lineno, "invalid attribute code %s",
1203 				 GET_RTX_NAME (GET_CODE (value)));
1204 	      have_error = 1;
1205 	      value = NULL_RTX;
1206 	    }
1207 	  if (value == NULL_RTX)
1208 	    continue;
1209 
1210 	  if ((attr = find_attr (&XSTR (XEXP (value, 0), 0), 0)) == NULL)
1211 	    {
1212 	      message_with_line (id->lineno, "unknown attribute %s",
1213 				 XSTR (XEXP (value, 0), 0));
1214 	      have_error = 1;
1215 	      continue;
1216 	    }
1217 
1218 	  XVECEXP (id->def, id->vec_idx, i) = value;
1219 	  XEXP (value, 1) = check_attr_value (XEXP (value, 1), attr);
1220 	}
1221     }
1222 }
1223 
1224 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1225    expressions by converting them into a COND.  This removes cases from this
1226    program.  Also, replace an attribute value of "*" with the default attribute
1227    value.  */
1228 
1229 static rtx
make_canonical(struct attr_desc * attr,rtx exp)1230 make_canonical (struct attr_desc *attr, rtx exp)
1231 {
1232   int i;
1233   rtx newexp;
1234 
1235   switch (GET_CODE (exp))
1236     {
1237     case CONST_INT:
1238       exp = make_numeric_value (INTVAL (exp));
1239       break;
1240 
1241     case CONST_STRING:
1242       if (! strcmp (XSTR (exp, 0), "*"))
1243 	{
1244 	  if (attr == 0 || attr->default_val == 0)
1245 	    fatal ("(attr_value \"*\") used in invalid context");
1246 	  exp = attr->default_val->value;
1247 	}
1248       else
1249 	XSTR (exp, 0) = DEF_ATTR_STRING (XSTR (exp, 0));
1250 
1251       break;
1252 
1253     case SYMBOL_REF:
1254       if (!attr->is_const || ATTR_IND_SIMPLIFIED_P (exp))
1255 	break;
1256       /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1257 	 This makes the COND something that won't be considered an arbitrary
1258 	 expression by walk_attr_value.  */
1259       ATTR_IND_SIMPLIFIED_P (exp) = 1;
1260       exp = check_attr_value (exp, attr);
1261       break;
1262 
1263     case IF_THEN_ELSE:
1264       newexp = rtx_alloc (COND);
1265       XVEC (newexp, 0) = rtvec_alloc (2);
1266       XVECEXP (newexp, 0, 0) = XEXP (exp, 0);
1267       XVECEXP (newexp, 0, 1) = XEXP (exp, 1);
1268 
1269       XEXP (newexp, 1) = XEXP (exp, 2);
1270 
1271       exp = newexp;
1272       /* Fall through to COND case since this is now a COND.  */
1273 
1274     case COND:
1275       {
1276 	int allsame = 1;
1277 	rtx defval;
1278 
1279 	/* First, check for degenerate COND.  */
1280 	if (XVECLEN (exp, 0) == 0)
1281 	  return make_canonical (attr, XEXP (exp, 1));
1282 	defval = XEXP (exp, 1) = make_canonical (attr, XEXP (exp, 1));
1283 
1284 	for (i = 0; i < XVECLEN (exp, 0); i += 2)
1285 	  {
1286 	    XVECEXP (exp, 0, i) = copy_boolean (XVECEXP (exp, 0, i));
1287 	    XVECEXP (exp, 0, i + 1)
1288 	      = make_canonical (attr, XVECEXP (exp, 0, i + 1));
1289 	    if (! rtx_equal_p (XVECEXP (exp, 0, i + 1), defval))
1290 	      allsame = 0;
1291 	  }
1292 	if (allsame)
1293 	  return defval;
1294       }
1295       break;
1296 
1297     default:
1298       break;
1299     }
1300 
1301   return exp;
1302 }
1303 
1304 static rtx
copy_boolean(rtx exp)1305 copy_boolean (rtx exp)
1306 {
1307   if (GET_CODE (exp) == AND || GET_CODE (exp) == IOR)
1308     return attr_rtx (GET_CODE (exp), copy_boolean (XEXP (exp, 0)),
1309 		     copy_boolean (XEXP (exp, 1)));
1310   if (GET_CODE (exp) == MATCH_OPERAND)
1311     {
1312       XSTR (exp, 1) = DEF_ATTR_STRING (XSTR (exp, 1));
1313       XSTR (exp, 2) = DEF_ATTR_STRING (XSTR (exp, 2));
1314     }
1315   else if (GET_CODE (exp) == EQ_ATTR)
1316     {
1317       XSTR (exp, 0) = DEF_ATTR_STRING (XSTR (exp, 0));
1318       XSTR (exp, 1) = DEF_ATTR_STRING (XSTR (exp, 1));
1319     }
1320 
1321   return exp;
1322 }
1323 
1324 /* Given a value and an attribute description, return a `struct attr_value *'
1325    that represents that value.  This is either an existing structure, if the
1326    value has been previously encountered, or a newly-created structure.
1327 
1328    `insn_code' is the code of an insn whose attribute has the specified
1329    value (-2 if not processing an insn).  We ensure that all insns for
1330    a given value have the same number of alternatives if the value checks
1331    alternatives.  */
1332 
1333 static struct attr_value *
get_attr_value(rtx value,struct attr_desc * attr,int insn_code)1334 get_attr_value (rtx value, struct attr_desc *attr, int insn_code)
1335 {
1336   struct attr_value *av;
1337   int num_alt = 0;
1338 
1339   value = make_canonical (attr, value);
1340   if (compares_alternatives_p (value))
1341     {
1342       if (insn_code < 0 || insn_alternatives == NULL)
1343 	fatal ("(eq_attr \"alternatives\" ...) used in non-insn context");
1344       else
1345 	num_alt = insn_alternatives[insn_code];
1346     }
1347 
1348   for (av = attr->first_value; av; av = av->next)
1349     if (rtx_equal_p (value, av->value)
1350 	&& (num_alt == 0 || av->first_insn == NULL
1351 	    || insn_alternatives[av->first_insn->def->insn_code]))
1352       return av;
1353 
1354   av = oballoc (sizeof (struct attr_value));
1355   av->value = value;
1356   av->next = attr->first_value;
1357   attr->first_value = av;
1358   av->first_insn = NULL;
1359   av->num_insns = 0;
1360   av->has_asm_insn = 0;
1361 
1362   return av;
1363 }
1364 
1365 /* After all DEFINE_DELAYs have been read in, create internal attributes
1366    to generate the required routines.
1367 
1368    First, we compute the number of delay slots for each insn (as a COND of
1369    each of the test expressions in DEFINE_DELAYs).  Then, if more than one
1370    delay type is specified, we compute a similar function giving the
1371    DEFINE_DELAY ordinal for each insn.
1372 
1373    Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1374    tells whether a given insn can be in that delay slot.
1375 
1376    Normal attribute filling and optimization expands these to contain the
1377    information needed to handle delay slots.  */
1378 
1379 static void
expand_delays(void)1380 expand_delays (void)
1381 {
1382   struct delay_desc *delay;
1383   rtx condexp;
1384   rtx newexp;
1385   int i;
1386   char *p;
1387 
1388   /* First, generate data for `num_delay_slots' function.  */
1389 
1390   condexp = rtx_alloc (COND);
1391   XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1392   XEXP (condexp, 1) = make_numeric_value (0);
1393 
1394   for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1395     {
1396       XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1397       XVECEXP (condexp, 0, i + 1)
1398 	= make_numeric_value (XVECLEN (delay->def, 1) / 3);
1399     }
1400 
1401   make_internal_attr (num_delay_slots_str, condexp, ATTR_NONE);
1402 
1403   /* If more than one delay type, do the same for computing the delay type.  */
1404   if (num_delays > 1)
1405     {
1406       condexp = rtx_alloc (COND);
1407       XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1408       XEXP (condexp, 1) = make_numeric_value (0);
1409 
1410       for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1411 	{
1412 	  XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1413 	  XVECEXP (condexp, 0, i + 1) = make_numeric_value (delay->num);
1414 	}
1415 
1416       make_internal_attr (delay_type_str, condexp, ATTR_SPECIAL);
1417     }
1418 
1419   /* For each delay possibility and delay slot, compute an eligibility
1420      attribute for non-annulled insns and for each type of annulled (annul
1421      if true and annul if false).  */
1422   for (delay = delays; delay; delay = delay->next)
1423     {
1424       for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
1425 	{
1426 	  condexp = XVECEXP (delay->def, 1, i);
1427 	  if (condexp == 0)
1428 	    condexp = false_rtx;
1429 	  newexp = attr_rtx (IF_THEN_ELSE, condexp,
1430 			     make_numeric_value (1), make_numeric_value (0));
1431 
1432 	  p = attr_printf (sizeof "*delay__" + MAX_DIGITS * 2,
1433 			   "*delay_%d_%d", delay->num, i / 3);
1434 	  make_internal_attr (p, newexp, ATTR_SPECIAL);
1435 
1436 	  if (have_annul_true)
1437 	    {
1438 	      condexp = XVECEXP (delay->def, 1, i + 1);
1439 	      if (condexp == 0) condexp = false_rtx;
1440 	      newexp = attr_rtx (IF_THEN_ELSE, condexp,
1441 				 make_numeric_value (1),
1442 				 make_numeric_value (0));
1443 	      p = attr_printf (sizeof "*annul_true__" + MAX_DIGITS * 2,
1444 			       "*annul_true_%d_%d", delay->num, i / 3);
1445 	      make_internal_attr (p, newexp, ATTR_SPECIAL);
1446 	    }
1447 
1448 	  if (have_annul_false)
1449 	    {
1450 	      condexp = XVECEXP (delay->def, 1, i + 2);
1451 	      if (condexp == 0) condexp = false_rtx;
1452 	      newexp = attr_rtx (IF_THEN_ELSE, condexp,
1453 				 make_numeric_value (1),
1454 				 make_numeric_value (0));
1455 	      p = attr_printf (sizeof "*annul_false__" + MAX_DIGITS * 2,
1456 			       "*annul_false_%d_%d", delay->num, i / 3);
1457 	      make_internal_attr (p, newexp, ATTR_SPECIAL);
1458 	    }
1459 	}
1460     }
1461 }
1462 
1463 /* Once all attributes and insns have been read and checked, we construct for
1464    each attribute value a list of all the insns that have that value for
1465    the attribute.  */
1466 
1467 static void
fill_attr(struct attr_desc * attr)1468 fill_attr (struct attr_desc *attr)
1469 {
1470   struct attr_value *av;
1471   struct insn_ent *ie;
1472   struct insn_def *id;
1473   int i;
1474   rtx value;
1475 
1476   /* Don't fill constant attributes.  The value is independent of
1477      any particular insn.  */
1478   if (attr->is_const)
1479     return;
1480 
1481   for (id = defs; id; id = id->next)
1482     {
1483       /* If no value is specified for this insn for this attribute, use the
1484 	 default.  */
1485       value = NULL;
1486       if (XVEC (id->def, id->vec_idx))
1487 	for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1488 	  if (! strcmp_check (XSTR (XEXP (XVECEXP (id->def, id->vec_idx, i), 0), 0),
1489 			      attr->name))
1490 	    value = XEXP (XVECEXP (id->def, id->vec_idx, i), 1);
1491 
1492       if (value == NULL)
1493 	av = attr->default_val;
1494       else
1495 	av = get_attr_value (value, attr, id->insn_code);
1496 
1497       ie = oballoc (sizeof (struct insn_ent));
1498       ie->def = id;
1499       insert_insn_ent (av, ie);
1500     }
1501 }
1502 
1503 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
1504    test that checks relative positions of insns (uses MATCH_DUP or PC).
1505    If so, replace it with what is obtained by passing the expression to
1506    ADDRESS_FN.  If not but it is a COND or IF_THEN_ELSE, call this routine
1507    recursively on each value (including the default value).  Otherwise,
1508    return the value returned by NO_ADDRESS_FN applied to EXP.  */
1509 
1510 static rtx
substitute_address(rtx exp,rtx (* no_address_fn)(rtx),rtx (* address_fn)(rtx))1511 substitute_address (rtx exp, rtx (*no_address_fn) (rtx),
1512 		    rtx (*address_fn) (rtx))
1513 {
1514   int i;
1515   rtx newexp;
1516 
1517   if (GET_CODE (exp) == COND)
1518     {
1519       /* See if any tests use addresses.  */
1520       address_used = 0;
1521       for (i = 0; i < XVECLEN (exp, 0); i += 2)
1522 	walk_attr_value (XVECEXP (exp, 0, i));
1523 
1524       if (address_used)
1525 	return (*address_fn) (exp);
1526 
1527       /* Make a new copy of this COND, replacing each element.  */
1528       newexp = rtx_alloc (COND);
1529       XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
1530       for (i = 0; i < XVECLEN (exp, 0); i += 2)
1531 	{
1532 	  XVECEXP (newexp, 0, i) = XVECEXP (exp, 0, i);
1533 	  XVECEXP (newexp, 0, i + 1)
1534 	    = substitute_address (XVECEXP (exp, 0, i + 1),
1535 				  no_address_fn, address_fn);
1536 	}
1537 
1538       XEXP (newexp, 1) = substitute_address (XEXP (exp, 1),
1539 					     no_address_fn, address_fn);
1540 
1541       return newexp;
1542     }
1543 
1544   else if (GET_CODE (exp) == IF_THEN_ELSE)
1545     {
1546       address_used = 0;
1547       walk_attr_value (XEXP (exp, 0));
1548       if (address_used)
1549 	return (*address_fn) (exp);
1550 
1551       return attr_rtx (IF_THEN_ELSE,
1552 		       substitute_address (XEXP (exp, 0),
1553 					   no_address_fn, address_fn),
1554 		       substitute_address (XEXP (exp, 1),
1555 					   no_address_fn, address_fn),
1556 		       substitute_address (XEXP (exp, 2),
1557 					   no_address_fn, address_fn));
1558     }
1559 
1560   return (*no_address_fn) (exp);
1561 }
1562 
1563 /* Make new attributes from the `length' attribute.  The following are made,
1564    each corresponding to a function called from `shorten_branches' or
1565    `get_attr_length':
1566 
1567    *insn_default_length		This is the length of the insn to be returned
1568 				by `get_attr_length' before `shorten_branches'
1569 				has been called.  In each case where the length
1570 				depends on relative addresses, the largest
1571 				possible is used.  This routine is also used
1572 				to compute the initial size of the insn.
1573 
1574    *insn_variable_length_p	This returns 1 if the insn's length depends
1575 				on relative addresses, zero otherwise.
1576 
1577    *insn_current_length		This is only called when it is known that the
1578 				insn has a variable length and returns the
1579 				current length, based on relative addresses.
1580   */
1581 
1582 static void
make_length_attrs(void)1583 make_length_attrs (void)
1584 {
1585   static const char *new_names[] =
1586     {
1587       "*insn_default_length",
1588       "*insn_min_length",
1589       "*insn_variable_length_p",
1590       "*insn_current_length"
1591     };
1592   static rtx (*const no_address_fn[]) (rtx)
1593     = {identity_fn,identity_fn, zero_fn, zero_fn};
1594   static rtx (*const address_fn[]) (rtx)
1595     = {max_fn, min_fn, one_fn, identity_fn};
1596   size_t i;
1597   struct attr_desc *length_attr, *new_attr;
1598   struct attr_value *av, *new_av;
1599   struct insn_ent *ie, *new_ie;
1600 
1601   /* See if length attribute is defined.  If so, it must be numeric.  Make
1602      it special so we don't output anything for it.  */
1603   length_attr = find_attr (&length_str, 0);
1604   if (length_attr == 0)
1605     return;
1606 
1607   if (! length_attr->is_numeric)
1608     fatal ("length attribute must be numeric");
1609 
1610   length_attr->is_const = 0;
1611   length_attr->is_special = 1;
1612 
1613   /* Make each new attribute, in turn.  */
1614   for (i = 0; i < ARRAY_SIZE (new_names); i++)
1615     {
1616       make_internal_attr (new_names[i],
1617 			  substitute_address (length_attr->default_val->value,
1618 					      no_address_fn[i], address_fn[i]),
1619 			  ATTR_NONE);
1620       new_attr = find_attr (&new_names[i], 0);
1621       for (av = length_attr->first_value; av; av = av->next)
1622 	for (ie = av->first_insn; ie; ie = ie->next)
1623 	  {
1624 	    new_av = get_attr_value (substitute_address (av->value,
1625 							 no_address_fn[i],
1626 							 address_fn[i]),
1627 				     new_attr, ie->def->insn_code);
1628 	    new_ie = oballoc (sizeof (struct insn_ent));
1629 	    new_ie->def = ie->def;
1630 	    insert_insn_ent (new_av, new_ie);
1631 	  }
1632     }
1633 }
1634 
1635 /* Utility functions called from above routine.  */
1636 
1637 static rtx
identity_fn(rtx exp)1638 identity_fn (rtx exp)
1639 {
1640   return exp;
1641 }
1642 
1643 static rtx
zero_fn(rtx exp ATTRIBUTE_UNUSED)1644 zero_fn (rtx exp ATTRIBUTE_UNUSED)
1645 {
1646   return make_numeric_value (0);
1647 }
1648 
1649 static rtx
one_fn(rtx exp ATTRIBUTE_UNUSED)1650 one_fn (rtx exp ATTRIBUTE_UNUSED)
1651 {
1652   return make_numeric_value (1);
1653 }
1654 
1655 static rtx
max_fn(rtx exp)1656 max_fn (rtx exp)
1657 {
1658   int unknown;
1659   return make_numeric_value (max_attr_value (exp, &unknown));
1660 }
1661 
1662 static rtx
min_fn(rtx exp)1663 min_fn (rtx exp)
1664 {
1665   int unknown;
1666   return make_numeric_value (min_attr_value (exp, &unknown));
1667 }
1668 
1669 static void
write_length_unit_log(void)1670 write_length_unit_log (void)
1671 {
1672   struct attr_desc *length_attr = find_attr (&length_str, 0);
1673   struct attr_value *av;
1674   struct insn_ent *ie;
1675   unsigned int length_unit_log, length_or;
1676   int unknown = 0;
1677 
1678   if (length_attr == 0)
1679     return;
1680   length_or = or_attr_value (length_attr->default_val->value, &unknown);
1681   for (av = length_attr->first_value; av; av = av->next)
1682     for (ie = av->first_insn; ie; ie = ie->next)
1683       length_or |= or_attr_value (av->value, &unknown);
1684 
1685   if (unknown)
1686     length_unit_log = 0;
1687   else
1688     {
1689       length_or = ~length_or;
1690       for (length_unit_log = 0; length_or & 1; length_or >>= 1)
1691 	length_unit_log++;
1692     }
1693   printf ("int length_unit_log = %u;\n", length_unit_log);
1694 }
1695 
1696 /* Take a COND expression and see if any of the conditions in it can be
1697    simplified.  If any are known true or known false for the particular insn
1698    code, the COND can be further simplified.
1699 
1700    Also call ourselves on any COND operations that are values of this COND.
1701 
1702    We do not modify EXP; rather, we make and return a new rtx.  */
1703 
1704 static rtx
simplify_cond(rtx exp,int insn_code,int insn_index)1705 simplify_cond (rtx exp, int insn_code, int insn_index)
1706 {
1707   int i, j;
1708   /* We store the desired contents here,
1709      then build a new expression if they don't match EXP.  */
1710   rtx defval = XEXP (exp, 1);
1711   rtx new_defval = XEXP (exp, 1);
1712   int len = XVECLEN (exp, 0);
1713   rtx *tests = xmalloc (len * sizeof (rtx));
1714   int allsame = 1;
1715   rtx ret;
1716 
1717   /* This lets us free all storage allocated below, if appropriate.  */
1718   obstack_finish (rtl_obstack);
1719 
1720   memcpy (tests, XVEC (exp, 0)->elem, len * sizeof (rtx));
1721 
1722   /* See if default value needs simplification.  */
1723   if (GET_CODE (defval) == COND)
1724     new_defval = simplify_cond (defval, insn_code, insn_index);
1725 
1726   /* Simplify the subexpressions, and see what tests we can get rid of.  */
1727 
1728   for (i = 0; i < len; i += 2)
1729     {
1730       rtx newtest, newval;
1731 
1732       /* Simplify this test.  */
1733       newtest = simplify_test_exp_in_temp (tests[i], insn_code, insn_index);
1734       tests[i] = newtest;
1735 
1736       newval = tests[i + 1];
1737       /* See if this value may need simplification.  */
1738       if (GET_CODE (newval) == COND)
1739 	newval = simplify_cond (newval, insn_code, insn_index);
1740 
1741       /* Look for ways to delete or combine this test.  */
1742       if (newtest == true_rtx)
1743 	{
1744 	  /* If test is true, make this value the default
1745 	     and discard this + any following tests.  */
1746 	  len = i;
1747 	  defval = tests[i + 1];
1748 	  new_defval = newval;
1749 	}
1750 
1751       else if (newtest == false_rtx)
1752 	{
1753 	  /* If test is false, discard it and its value.  */
1754 	  for (j = i; j < len - 2; j++)
1755 	    tests[j] = tests[j + 2];
1756 	  i -= 2;
1757 	  len -= 2;
1758 	}
1759 
1760       else if (i > 0 && attr_equal_p (newval, tests[i - 1]))
1761 	{
1762 	  /* If this value and the value for the prev test are the same,
1763 	     merge the tests.  */
1764 
1765 	  tests[i - 2]
1766 	    = insert_right_side (IOR, tests[i - 2], newtest,
1767 				 insn_code, insn_index);
1768 
1769 	  /* Delete this test/value.  */
1770 	  for (j = i; j < len - 2; j++)
1771 	    tests[j] = tests[j + 2];
1772 	  len -= 2;
1773 	  i -= 2;
1774 	}
1775 
1776       else
1777 	tests[i + 1] = newval;
1778     }
1779 
1780   /* If the last test in a COND has the same value
1781      as the default value, that test isn't needed.  */
1782 
1783   while (len > 0 && attr_equal_p (tests[len - 1], new_defval))
1784     len -= 2;
1785 
1786   /* See if we changed anything.  */
1787   if (len != XVECLEN (exp, 0) || new_defval != XEXP (exp, 1))
1788     allsame = 0;
1789   else
1790     for (i = 0; i < len; i++)
1791       if (! attr_equal_p (tests[i], XVECEXP (exp, 0, i)))
1792 	{
1793 	  allsame = 0;
1794 	  break;
1795 	}
1796 
1797   if (len == 0)
1798     {
1799       if (GET_CODE (defval) == COND)
1800 	ret = simplify_cond (defval, insn_code, insn_index);
1801       else
1802 	ret = defval;
1803     }
1804   else if (allsame)
1805     ret = exp;
1806   else
1807     {
1808       rtx newexp = rtx_alloc (COND);
1809 
1810       XVEC (newexp, 0) = rtvec_alloc (len);
1811       memcpy (XVEC (newexp, 0)->elem, tests, len * sizeof (rtx));
1812       XEXP (newexp, 1) = new_defval;
1813       ret = newexp;
1814     }
1815   free (tests);
1816   return ret;
1817 }
1818 
1819 /* Remove an insn entry from an attribute value.  */
1820 
1821 static void
remove_insn_ent(struct attr_value * av,struct insn_ent * ie)1822 remove_insn_ent (struct attr_value *av, struct insn_ent *ie)
1823 {
1824   struct insn_ent *previe;
1825 
1826   if (av->first_insn == ie)
1827     av->first_insn = ie->next;
1828   else
1829     {
1830       for (previe = av->first_insn; previe->next != ie; previe = previe->next)
1831 	;
1832       previe->next = ie->next;
1833     }
1834 
1835   av->num_insns--;
1836   if (ie->def->insn_code == -1)
1837     av->has_asm_insn = 0;
1838 
1839   num_insn_ents--;
1840 }
1841 
1842 /* Insert an insn entry in an attribute value list.  */
1843 
1844 static void
insert_insn_ent(struct attr_value * av,struct insn_ent * ie)1845 insert_insn_ent (struct attr_value *av, struct insn_ent *ie)
1846 {
1847   ie->next = av->first_insn;
1848   av->first_insn = ie;
1849   av->num_insns++;
1850   if (ie->def->insn_code == -1)
1851     av->has_asm_insn = 1;
1852 
1853   num_insn_ents++;
1854 }
1855 
1856 /* This is a utility routine to take an expression that is a tree of either
1857    AND or IOR expressions and insert a new term.  The new term will be
1858    inserted at the right side of the first node whose code does not match
1859    the root.  A new node will be created with the root's code.  Its left
1860    side will be the old right side and its right side will be the new
1861    term.
1862 
1863    If the `term' is itself a tree, all its leaves will be inserted.  */
1864 
1865 static rtx
insert_right_side(enum rtx_code code,rtx exp,rtx term,int insn_code,int insn_index)1866 insert_right_side (enum rtx_code code, rtx exp, rtx term, int insn_code, int insn_index)
1867 {
1868   rtx newexp;
1869 
1870   /* Avoid consing in some special cases.  */
1871   if (code == AND && term == true_rtx)
1872     return exp;
1873   if (code == AND && term == false_rtx)
1874     return false_rtx;
1875   if (code == AND && exp == true_rtx)
1876     return term;
1877   if (code == AND && exp == false_rtx)
1878     return false_rtx;
1879   if (code == IOR && term == true_rtx)
1880     return true_rtx;
1881   if (code == IOR && term == false_rtx)
1882     return exp;
1883   if (code == IOR && exp == true_rtx)
1884     return true_rtx;
1885   if (code == IOR && exp == false_rtx)
1886     return term;
1887   if (attr_equal_p (exp, term))
1888     return exp;
1889 
1890   if (GET_CODE (term) == code)
1891     {
1892       exp = insert_right_side (code, exp, XEXP (term, 0),
1893 			       insn_code, insn_index);
1894       exp = insert_right_side (code, exp, XEXP (term, 1),
1895 			       insn_code, insn_index);
1896 
1897       return exp;
1898     }
1899 
1900   if (GET_CODE (exp) == code)
1901     {
1902       rtx new = insert_right_side (code, XEXP (exp, 1),
1903 				   term, insn_code, insn_index);
1904       if (new != XEXP (exp, 1))
1905 	/* Make a copy of this expression and call recursively.  */
1906 	newexp = attr_rtx (code, XEXP (exp, 0), new);
1907       else
1908 	newexp = exp;
1909     }
1910   else
1911     {
1912       /* Insert the new term.  */
1913       newexp = attr_rtx (code, exp, term);
1914     }
1915 
1916   return simplify_test_exp_in_temp (newexp, insn_code, insn_index);
1917 }
1918 
1919 /* If we have an expression which AND's a bunch of
1920 	(not (eq_attrq "alternative" "n"))
1921    terms, we may have covered all or all but one of the possible alternatives.
1922    If so, we can optimize.  Similarly for IOR's of EQ_ATTR.
1923 
1924    This routine is passed an expression and either AND or IOR.  It returns a
1925    bitmask indicating which alternatives are mentioned within EXP.  */
1926 
1927 static int
compute_alternative_mask(rtx exp,enum rtx_code code)1928 compute_alternative_mask (rtx exp, enum rtx_code code)
1929 {
1930   const char *string;
1931   if (GET_CODE (exp) == code)
1932     return compute_alternative_mask (XEXP (exp, 0), code)
1933 	   | compute_alternative_mask (XEXP (exp, 1), code);
1934 
1935   else if (code == AND && GET_CODE (exp) == NOT
1936 	   && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
1937 	   && XSTR (XEXP (exp, 0), 0) == alternative_name)
1938     string = XSTR (XEXP (exp, 0), 1);
1939 
1940   else if (code == IOR && GET_CODE (exp) == EQ_ATTR
1941 	   && XSTR (exp, 0) == alternative_name)
1942     string = XSTR (exp, 1);
1943 
1944   else if (GET_CODE (exp) == EQ_ATTR_ALT)
1945     {
1946       if (code == AND && XINT (exp, 1))
1947 	return XINT (exp, 0);
1948 
1949       if (code == IOR && !XINT (exp, 1))
1950 	return XINT (exp, 0);
1951 
1952       return 0;
1953     }
1954   else
1955     return 0;
1956 
1957   if (string[1] == 0)
1958     return 1 << (string[0] - '0');
1959   return 1 << atoi (string);
1960 }
1961 
1962 /* Given I, a single-bit mask, return RTX to compare the `alternative'
1963    attribute with the value represented by that bit.  */
1964 
1965 static rtx
make_alternative_compare(int mask)1966 make_alternative_compare (int mask)
1967 {
1968   return mk_attr_alt (mask);
1969 }
1970 
1971 /* If we are processing an (eq_attr "attr" "value") test, we find the value
1972    of "attr" for this insn code.  From that value, we can compute a test
1973    showing when the EQ_ATTR will be true.  This routine performs that
1974    computation.  If a test condition involves an address, we leave the EQ_ATTR
1975    intact because addresses are only valid for the `length' attribute.
1976 
1977    EXP is the EQ_ATTR expression and VALUE is the value of that attribute
1978    for the insn corresponding to INSN_CODE and INSN_INDEX.  */
1979 
1980 static rtx
evaluate_eq_attr(rtx exp,rtx value,int insn_code,int insn_index)1981 evaluate_eq_attr (rtx exp, rtx value, int insn_code, int insn_index)
1982 {
1983   rtx orexp, andexp;
1984   rtx right;
1985   rtx newexp;
1986   int i;
1987 
1988   switch (GET_CODE (value))
1989     {
1990     case CONST_STRING:
1991       if (! strcmp_check (XSTR (value, 0), XSTR (exp, 1)))
1992 	newexp = true_rtx;
1993       else
1994 	newexp = false_rtx;
1995       break;
1996 
1997     case SYMBOL_REF:
1998       {
1999 	char *p;
2000 	char string[256];
2001 
2002 	gcc_assert (GET_CODE (exp) == EQ_ATTR);
2003 	gcc_assert (strlen (XSTR (exp, 0)) + strlen (XSTR (exp, 1)) + 2
2004 		    <= 256);
2005 
2006 	strcpy (string, XSTR (exp, 0));
2007 	strcat (string, "_");
2008 	strcat (string, XSTR (exp, 1));
2009 	for (p = string; *p; p++)
2010 	  *p = TOUPPER (*p);
2011 
2012 	newexp = attr_rtx (EQ, value,
2013 			   attr_rtx (SYMBOL_REF,
2014 				     DEF_ATTR_STRING (string)));
2015 	break;
2016       }
2017 
2018     case COND:
2019       /* We construct an IOR of all the cases for which the
2020 	 requested attribute value is present.  Since we start with
2021 	 FALSE, if it is not present, FALSE will be returned.
2022 
2023 	 Each case is the AND of the NOT's of the previous conditions with the
2024 	 current condition; in the default case the current condition is TRUE.
2025 
2026 	 For each possible COND value, call ourselves recursively.
2027 
2028 	 The extra TRUE and FALSE expressions will be eliminated by another
2029 	 call to the simplification routine.  */
2030 
2031       orexp = false_rtx;
2032       andexp = true_rtx;
2033 
2034       for (i = 0; i < XVECLEN (value, 0); i += 2)
2035 	{
2036 	  rtx this = simplify_test_exp_in_temp (XVECEXP (value, 0, i),
2037 						insn_code, insn_index);
2038 
2039 	  right = insert_right_side (AND, andexp, this,
2040 				     insn_code, insn_index);
2041 	  right = insert_right_side (AND, right,
2042 				     evaluate_eq_attr (exp,
2043 						       XVECEXP (value, 0,
2044 								i + 1),
2045 						       insn_code, insn_index),
2046 				     insn_code, insn_index);
2047 	  orexp = insert_right_side (IOR, orexp, right,
2048 				     insn_code, insn_index);
2049 
2050 	  /* Add this condition into the AND expression.  */
2051 	  newexp = attr_rtx (NOT, this);
2052 	  andexp = insert_right_side (AND, andexp, newexp,
2053 				      insn_code, insn_index);
2054 	}
2055 
2056       /* Handle the default case.  */
2057       right = insert_right_side (AND, andexp,
2058 				 evaluate_eq_attr (exp, XEXP (value, 1),
2059 						   insn_code, insn_index),
2060 				 insn_code, insn_index);
2061       newexp = insert_right_side (IOR, orexp, right, insn_code, insn_index);
2062       break;
2063 
2064     default:
2065       gcc_unreachable ();
2066     }
2067 
2068   /* If uses an address, must return original expression.  But set the
2069      ATTR_IND_SIMPLIFIED_P bit so we don't try to simplify it again.  */
2070 
2071   address_used = 0;
2072   walk_attr_value (newexp);
2073 
2074   if (address_used)
2075     {
2076       if (! ATTR_IND_SIMPLIFIED_P (exp))
2077 	return copy_rtx_unchanging (exp);
2078       return exp;
2079     }
2080   else
2081     return newexp;
2082 }
2083 
2084 /* This routine is called when an AND of a term with a tree of AND's is
2085    encountered.  If the term or its complement is present in the tree, it
2086    can be replaced with TRUE or FALSE, respectively.
2087 
2088    Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2089    be true and hence are complementary.
2090 
2091    There is one special case:  If we see
2092 	(and (not (eq_attr "att" "v1"))
2093 	     (eq_attr "att" "v2"))
2094    this can be replaced by (eq_attr "att" "v2").  To do this we need to
2095    replace the term, not anything in the AND tree.  So we pass a pointer to
2096    the term.  */
2097 
2098 static rtx
simplify_and_tree(rtx exp,rtx * pterm,int insn_code,int insn_index)2099 simplify_and_tree (rtx exp, rtx *pterm, int insn_code, int insn_index)
2100 {
2101   rtx left, right;
2102   rtx newexp;
2103   rtx temp;
2104   int left_eliminates_term, right_eliminates_term;
2105 
2106   if (GET_CODE (exp) == AND)
2107     {
2108       left  = simplify_and_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
2109       right = simplify_and_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2110       if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2111 	{
2112 	  newexp = attr_rtx (AND, left, right);
2113 
2114 	  exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2115 	}
2116     }
2117 
2118   else if (GET_CODE (exp) == IOR)
2119     {
2120       /* For the IOR case, we do the same as above, except that we can
2121          only eliminate `term' if both sides of the IOR would do so.  */
2122       temp = *pterm;
2123       left = simplify_and_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
2124       left_eliminates_term = (temp == true_rtx);
2125 
2126       temp = *pterm;
2127       right = simplify_and_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2128       right_eliminates_term = (temp == true_rtx);
2129 
2130       if (left_eliminates_term && right_eliminates_term)
2131 	*pterm = true_rtx;
2132 
2133       if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2134 	{
2135 	  newexp = attr_rtx (IOR, left, right);
2136 
2137 	  exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2138 	}
2139     }
2140 
2141   /* Check for simplifications.  Do some extra checking here since this
2142      routine is called so many times.  */
2143 
2144   if (exp == *pterm)
2145     return true_rtx;
2146 
2147   else if (GET_CODE (exp) == NOT && XEXP (exp, 0) == *pterm)
2148     return false_rtx;
2149 
2150   else if (GET_CODE (*pterm) == NOT && exp == XEXP (*pterm, 0))
2151     return false_rtx;
2152 
2153   else if (GET_CODE (exp) == EQ_ATTR_ALT && GET_CODE (*pterm) == EQ_ATTR_ALT)
2154     {
2155       if (attr_alt_subset_p (*pterm, exp))
2156 	return true_rtx;
2157 
2158       if (attr_alt_subset_of_compl_p (*pterm, exp))
2159 	return false_rtx;
2160 
2161       if (attr_alt_subset_p (exp, *pterm))
2162 	*pterm = true_rtx;
2163 
2164       return exp;
2165     }
2166 
2167   else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == EQ_ATTR)
2168     {
2169       if (XSTR (exp, 0) != XSTR (*pterm, 0))
2170 	return exp;
2171 
2172       if (! strcmp_check (XSTR (exp, 1), XSTR (*pterm, 1)))
2173 	return true_rtx;
2174       else
2175 	return false_rtx;
2176     }
2177 
2178   else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
2179 	   && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
2180     {
2181       if (XSTR (*pterm, 0) != XSTR (XEXP (exp, 0), 0))
2182 	return exp;
2183 
2184       if (! strcmp_check (XSTR (*pterm, 1), XSTR (XEXP (exp, 0), 1)))
2185 	return false_rtx;
2186       else
2187 	return true_rtx;
2188     }
2189 
2190   else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
2191 	   && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR)
2192     {
2193       if (XSTR (exp, 0) != XSTR (XEXP (*pterm, 0), 0))
2194 	return exp;
2195 
2196       if (! strcmp_check (XSTR (exp, 1), XSTR (XEXP (*pterm, 0), 1)))
2197 	return false_rtx;
2198       else
2199 	*pterm = true_rtx;
2200     }
2201 
2202   else if (GET_CODE (exp) == NOT && GET_CODE (*pterm) == NOT)
2203     {
2204       if (attr_equal_p (XEXP (exp, 0), XEXP (*pterm, 0)))
2205 	return true_rtx;
2206     }
2207 
2208   else if (GET_CODE (exp) == NOT)
2209     {
2210       if (attr_equal_p (XEXP (exp, 0), *pterm))
2211 	return false_rtx;
2212     }
2213 
2214   else if (GET_CODE (*pterm) == NOT)
2215     {
2216       if (attr_equal_p (XEXP (*pterm, 0), exp))
2217 	return false_rtx;
2218     }
2219 
2220   else if (attr_equal_p (exp, *pterm))
2221     return true_rtx;
2222 
2223   return exp;
2224 }
2225 
2226 /* Similar to `simplify_and_tree', but for IOR trees.  */
2227 
2228 static rtx
simplify_or_tree(rtx exp,rtx * pterm,int insn_code,int insn_index)2229 simplify_or_tree (rtx exp, rtx *pterm, int insn_code, int insn_index)
2230 {
2231   rtx left, right;
2232   rtx newexp;
2233   rtx temp;
2234   int left_eliminates_term, right_eliminates_term;
2235 
2236   if (GET_CODE (exp) == IOR)
2237     {
2238       left  = simplify_or_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
2239       right = simplify_or_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2240       if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2241 	{
2242 	  newexp = attr_rtx (GET_CODE (exp), left, right);
2243 
2244 	  exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2245 	}
2246     }
2247 
2248   else if (GET_CODE (exp) == AND)
2249     {
2250       /* For the AND case, we do the same as above, except that we can
2251          only eliminate `term' if both sides of the AND would do so.  */
2252       temp = *pterm;
2253       left = simplify_or_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
2254       left_eliminates_term = (temp == false_rtx);
2255 
2256       temp = *pterm;
2257       right = simplify_or_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2258       right_eliminates_term = (temp == false_rtx);
2259 
2260       if (left_eliminates_term && right_eliminates_term)
2261 	*pterm = false_rtx;
2262 
2263       if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2264 	{
2265 	  newexp = attr_rtx (GET_CODE (exp), left, right);
2266 
2267 	  exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2268 	}
2269     }
2270 
2271   if (attr_equal_p (exp, *pterm))
2272     return false_rtx;
2273 
2274   else if (GET_CODE (exp) == NOT && attr_equal_p (XEXP (exp, 0), *pterm))
2275     return true_rtx;
2276 
2277   else if (GET_CODE (*pterm) == NOT && attr_equal_p (XEXP (*pterm, 0), exp))
2278     return true_rtx;
2279 
2280   else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
2281 	   && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
2282 	   && XSTR (*pterm, 0) == XSTR (XEXP (exp, 0), 0))
2283     *pterm = false_rtx;
2284 
2285   else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
2286 	   && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR
2287 	   && XSTR (exp, 0) == XSTR (XEXP (*pterm, 0), 0))
2288     return false_rtx;
2289 
2290   return exp;
2291 }
2292 
2293 /* Compute approximate cost of the expression.  Used to decide whether
2294    expression is cheap enough for inline.  */
2295 static int
attr_rtx_cost(rtx x)2296 attr_rtx_cost (rtx x)
2297 {
2298   int cost = 0;
2299   enum rtx_code code;
2300   if (!x)
2301     return 0;
2302   code = GET_CODE (x);
2303   switch (code)
2304     {
2305     case MATCH_OPERAND:
2306       if (XSTR (x, 1)[0])
2307 	return 10;
2308       else
2309 	return 0;
2310 
2311     case EQ_ATTR_ALT:
2312       return 0;
2313 
2314     case EQ_ATTR:
2315       /* Alternatives don't result into function call.  */
2316       if (!strcmp_check (XSTR (x, 0), alternative_name))
2317 	return 0;
2318       else
2319 	return 5;
2320     default:
2321       {
2322 	int i, j;
2323 	const char *fmt = GET_RTX_FORMAT (code);
2324 	for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
2325 	  {
2326 	    switch (fmt[i])
2327 	      {
2328 	      case 'V':
2329 	      case 'E':
2330 		for (j = 0; j < XVECLEN (x, i); j++)
2331 		  cost += attr_rtx_cost (XVECEXP (x, i, j));
2332 		break;
2333 	      case 'e':
2334 		cost += attr_rtx_cost (XEXP (x, i));
2335 		break;
2336 	      }
2337 	  }
2338       }
2339       break;
2340     }
2341   return cost;
2342 }
2343 
2344 /* Simplify test expression and use temporary obstack in order to avoid
2345    memory bloat.  Use ATTR_IND_SIMPLIFIED to avoid unnecessary simplifications
2346    and avoid unnecessary copying if possible.  */
2347 
2348 static rtx
simplify_test_exp_in_temp(rtx exp,int insn_code,int insn_index)2349 simplify_test_exp_in_temp (rtx exp, int insn_code, int insn_index)
2350 {
2351   rtx x;
2352   struct obstack *old;
2353   if (ATTR_IND_SIMPLIFIED_P (exp))
2354     return exp;
2355   old = rtl_obstack;
2356   rtl_obstack = temp_obstack;
2357   x = simplify_test_exp (exp, insn_code, insn_index);
2358   rtl_obstack = old;
2359   if (x == exp || rtl_obstack == temp_obstack)
2360     return x;
2361   return attr_copy_rtx (x);
2362 }
2363 
2364 /* Returns true if S1 is a subset of S2.  */
2365 
2366 static bool
attr_alt_subset_p(rtx s1,rtx s2)2367 attr_alt_subset_p (rtx s1, rtx s2)
2368 {
2369   switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2370     {
2371     case (0 << 1) | 0:
2372       return !(XINT (s1, 0) &~ XINT (s2, 0));
2373 
2374     case (0 << 1) | 1:
2375       return !(XINT (s1, 0) & XINT (s2, 0));
2376 
2377     case (1 << 1) | 0:
2378       return false;
2379 
2380     case (1 << 1) | 1:
2381       return !(XINT (s2, 0) &~ XINT (s1, 0));
2382 
2383     default:
2384       gcc_unreachable ();
2385     }
2386 }
2387 
2388 /* Returns true if S1 is a subset of complement of S2.  */
2389 
2390 static bool
attr_alt_subset_of_compl_p(rtx s1,rtx s2)2391 attr_alt_subset_of_compl_p (rtx s1, rtx s2)
2392 {
2393   switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2394     {
2395     case (0 << 1) | 0:
2396       return !(XINT (s1, 0) & XINT (s2, 0));
2397 
2398     case (0 << 1) | 1:
2399       return !(XINT (s1, 0) & ~XINT (s2, 0));
2400 
2401     case (1 << 1) | 0:
2402       return !(XINT (s2, 0) &~ XINT (s1, 0));
2403 
2404     case (1 << 1) | 1:
2405       return false;
2406 
2407     default:
2408       gcc_unreachable ();
2409     }
2410 }
2411 
2412 /* Return EQ_ATTR_ALT expression representing intersection of S1 and S2.  */
2413 
2414 static rtx
attr_alt_intersection(rtx s1,rtx s2)2415 attr_alt_intersection (rtx s1, rtx s2)
2416 {
2417   rtx result = rtx_alloc (EQ_ATTR_ALT);
2418 
2419   switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2420     {
2421     case (0 << 1) | 0:
2422       XINT (result, 0) = XINT (s1, 0) & XINT (s2, 0);
2423       break;
2424     case (0 << 1) | 1:
2425       XINT (result, 0) = XINT (s1, 0) & ~XINT (s2, 0);
2426       break;
2427     case (1 << 1) | 0:
2428       XINT (result, 0) = XINT (s2, 0) & ~XINT (s1, 0);
2429       break;
2430     case (1 << 1) | 1:
2431       XINT (result, 0) = XINT (s1, 0) | XINT (s2, 0);
2432       break;
2433     default:
2434       gcc_unreachable ();
2435     }
2436   XINT (result, 1) = XINT (s1, 1) & XINT (s2, 1);
2437 
2438   return result;
2439 }
2440 
2441 /* Return EQ_ATTR_ALT expression representing union of S1 and S2.  */
2442 
2443 static rtx
attr_alt_union(rtx s1,rtx s2)2444 attr_alt_union (rtx s1, rtx s2)
2445 {
2446   rtx result = rtx_alloc (EQ_ATTR_ALT);
2447 
2448   switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2449     {
2450     case (0 << 1) | 0:
2451       XINT (result, 0) = XINT (s1, 0) | XINT (s2, 0);
2452       break;
2453     case (0 << 1) | 1:
2454       XINT (result, 0) = XINT (s2, 0) & ~XINT (s1, 0);
2455       break;
2456     case (1 << 1) | 0:
2457       XINT (result, 0) = XINT (s1, 0) & ~XINT (s2, 0);
2458       break;
2459     case (1 << 1) | 1:
2460       XINT (result, 0) = XINT (s1, 0) & XINT (s2, 0);
2461       break;
2462     default:
2463       gcc_unreachable ();
2464     }
2465 
2466   XINT (result, 1) = XINT (s1, 1) | XINT (s2, 1);
2467   return result;
2468 }
2469 
2470 /* Return EQ_ATTR_ALT expression representing complement of S.  */
2471 
2472 static rtx
attr_alt_complement(rtx s)2473 attr_alt_complement (rtx s)
2474 {
2475   rtx result = rtx_alloc (EQ_ATTR_ALT);
2476 
2477   XINT (result, 0) = XINT (s, 0);
2478   XINT (result, 1) = 1 - XINT (s, 1);
2479 
2480   return result;
2481 }
2482 
2483 /* Return EQ_ATTR_ALT expression representing set containing elements set
2484    in E.  */
2485 
2486 static rtx
mk_attr_alt(int e)2487 mk_attr_alt (int e)
2488 {
2489   rtx result = rtx_alloc (EQ_ATTR_ALT);
2490 
2491   XINT (result, 0) = e;
2492   XINT (result, 1) = 0;
2493 
2494   return result;
2495 }
2496 
2497 /* Given an expression, see if it can be simplified for a particular insn
2498    code based on the values of other attributes being tested.  This can
2499    eliminate nested get_attr_... calls.
2500 
2501    Note that if an endless recursion is specified in the patterns, the
2502    optimization will loop.  However, it will do so in precisely the cases where
2503    an infinite recursion loop could occur during compilation.  It's better that
2504    it occurs here!  */
2505 
2506 static rtx
simplify_test_exp(rtx exp,int insn_code,int insn_index)2507 simplify_test_exp (rtx exp, int insn_code, int insn_index)
2508 {
2509   rtx left, right;
2510   struct attr_desc *attr;
2511   struct attr_value *av;
2512   struct insn_ent *ie;
2513   int i;
2514   rtx newexp = exp;
2515   bool left_alt, right_alt;
2516 
2517   /* Don't re-simplify something we already simplified.  */
2518   if (ATTR_IND_SIMPLIFIED_P (exp) || ATTR_CURR_SIMPLIFIED_P (exp))
2519     return exp;
2520 
2521   switch (GET_CODE (exp))
2522     {
2523     case AND:
2524       left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2525       if (left == false_rtx)
2526 	return false_rtx;
2527       right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
2528       if (right == false_rtx)
2529 	return false_rtx;
2530 
2531       if (GET_CODE (left) == EQ_ATTR_ALT
2532 	  && GET_CODE (right) == EQ_ATTR_ALT)
2533 	{
2534 	  exp = attr_alt_intersection (left, right);
2535 	  return simplify_test_exp (exp, insn_code, insn_index);
2536 	}
2537 
2538       /* If either side is an IOR and we have (eq_attr "alternative" ..")
2539 	 present on both sides, apply the distributive law since this will
2540 	 yield simplifications.  */
2541       if ((GET_CODE (left) == IOR || GET_CODE (right) == IOR)
2542 	  && compute_alternative_mask (left, IOR)
2543 	  && compute_alternative_mask (right, IOR))
2544 	{
2545 	  if (GET_CODE (left) == IOR)
2546 	    {
2547 	      rtx tem = left;
2548 	      left = right;
2549 	      right = tem;
2550 	    }
2551 
2552 	  newexp = attr_rtx (IOR,
2553 			     attr_rtx (AND, left, XEXP (right, 0)),
2554 			     attr_rtx (AND, left, XEXP (right, 1)));
2555 
2556 	  return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2557 	}
2558 
2559       /* Try with the term on both sides.  */
2560       right = simplify_and_tree (right, &left, insn_code, insn_index);
2561       if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
2562 	left = simplify_and_tree (left, &right, insn_code, insn_index);
2563 
2564       if (left == false_rtx || right == false_rtx)
2565 	return false_rtx;
2566       else if (left == true_rtx)
2567 	{
2568 	  return right;
2569 	}
2570       else if (right == true_rtx)
2571 	{
2572 	  return left;
2573 	}
2574       /* See if all or all but one of the insn's alternatives are specified
2575 	 in this tree.  Optimize if so.  */
2576 
2577       if (GET_CODE (left) == NOT)
2578 	left_alt = (GET_CODE (XEXP (left, 0)) == EQ_ATTR
2579 		    && XSTR (XEXP (left, 0), 0) == alternative_name);
2580       else
2581 	left_alt = (GET_CODE (left) == EQ_ATTR_ALT
2582 		    && XINT (left, 1));
2583 
2584       if (GET_CODE (right) == NOT)
2585 	right_alt = (GET_CODE (XEXP (right, 0)) == EQ_ATTR
2586 		     && XSTR (XEXP (right, 0), 0) == alternative_name);
2587       else
2588 	right_alt = (GET_CODE (right) == EQ_ATTR_ALT
2589 		     && XINT (right, 1));
2590 
2591       if (insn_code >= 0
2592 	  && (GET_CODE (left) == AND
2593 	      || left_alt
2594 	      || GET_CODE (right) == AND
2595 	      || right_alt))
2596 	{
2597 	  i = compute_alternative_mask (exp, AND);
2598 	  if (i & ~insn_alternatives[insn_code])
2599 	    fatal ("invalid alternative specified for pattern number %d",
2600 		   insn_index);
2601 
2602 	  /* If all alternatives are excluded, this is false.  */
2603 	  i ^= insn_alternatives[insn_code];
2604 	  if (i == 0)
2605 	    return false_rtx;
2606 	  else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
2607 	    {
2608 	      /* If just one excluded, AND a comparison with that one to the
2609 		 front of the tree.  The others will be eliminated by
2610 		 optimization.  We do not want to do this if the insn has one
2611 		 alternative and we have tested none of them!  */
2612 	      left = make_alternative_compare (i);
2613 	      right = simplify_and_tree (exp, &left, insn_code, insn_index);
2614 	      newexp = attr_rtx (AND, left, right);
2615 
2616 	      return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2617 	    }
2618 	}
2619 
2620       if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2621 	{
2622 	  newexp = attr_rtx (AND, left, right);
2623 	  return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2624 	}
2625       break;
2626 
2627     case IOR:
2628       left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2629       if (left == true_rtx)
2630 	return true_rtx;
2631       right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
2632       if (right == true_rtx)
2633 	return true_rtx;
2634 
2635       if (GET_CODE (left) == EQ_ATTR_ALT
2636 	  && GET_CODE (right) == EQ_ATTR_ALT)
2637 	{
2638 	  exp = attr_alt_union (left, right);
2639 	  return simplify_test_exp (exp, insn_code, insn_index);
2640 	}
2641 
2642       right = simplify_or_tree (right, &left, insn_code, insn_index);
2643       if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
2644 	left = simplify_or_tree (left, &right, insn_code, insn_index);
2645 
2646       if (right == true_rtx || left == true_rtx)
2647 	return true_rtx;
2648       else if (left == false_rtx)
2649 	{
2650 	  return right;
2651 	}
2652       else if (right == false_rtx)
2653 	{
2654 	  return left;
2655 	}
2656 
2657       /* Test for simple cases where the distributive law is useful.  I.e.,
2658 	    convert (ior (and (x) (y))
2659 			 (and (x) (z)))
2660 	    to      (and (x)
2661 			 (ior (y) (z)))
2662        */
2663 
2664       else if (GET_CODE (left) == AND && GET_CODE (right) == AND
2665 	       && attr_equal_p (XEXP (left, 0), XEXP (right, 0)))
2666 	{
2667 	  newexp = attr_rtx (IOR, XEXP (left, 1), XEXP (right, 1));
2668 
2669 	  left = XEXP (left, 0);
2670 	  right = newexp;
2671 	  newexp = attr_rtx (AND, left, right);
2672 	  return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2673 	}
2674 
2675       /* See if all or all but one of the insn's alternatives are specified
2676 	 in this tree.  Optimize if so.  */
2677 
2678       else if (insn_code >= 0
2679 	       && (GET_CODE (left) == IOR
2680 		   || (GET_CODE (left) == EQ_ATTR_ALT
2681 		       && !XINT (left, 1))
2682 		   || (GET_CODE (left) == EQ_ATTR
2683 		       && XSTR (left, 0) == alternative_name)
2684 		   || GET_CODE (right) == IOR
2685 		   || (GET_CODE (right) == EQ_ATTR_ALT
2686 		       && !XINT (right, 1))
2687 		   || (GET_CODE (right) == EQ_ATTR
2688 		       && XSTR (right, 0) == alternative_name)))
2689 	{
2690 	  i = compute_alternative_mask (exp, IOR);
2691 	  if (i & ~insn_alternatives[insn_code])
2692 	    fatal ("invalid alternative specified for pattern number %d",
2693 		   insn_index);
2694 
2695 	  /* If all alternatives are included, this is true.  */
2696 	  i ^= insn_alternatives[insn_code];
2697 	  if (i == 0)
2698 	    return true_rtx;
2699 	  else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
2700 	    {
2701 	      /* If just one excluded, IOR a comparison with that one to the
2702 		 front of the tree.  The others will be eliminated by
2703 		 optimization.  We do not want to do this if the insn has one
2704 		 alternative and we have tested none of them!  */
2705 	      left = make_alternative_compare (i);
2706 	      right = simplify_and_tree (exp, &left, insn_code, insn_index);
2707 	      newexp = attr_rtx (IOR, attr_rtx (NOT, left), right);
2708 
2709 	      return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2710 	    }
2711 	}
2712 
2713       if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2714 	{
2715 	  newexp = attr_rtx (IOR, left, right);
2716 	  return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2717 	}
2718       break;
2719 
2720     case NOT:
2721       if (GET_CODE (XEXP (exp, 0)) == NOT)
2722 	{
2723 	  left = SIMPLIFY_TEST_EXP (XEXP (XEXP (exp, 0), 0),
2724 				    insn_code, insn_index);
2725 	  return left;
2726 	}
2727 
2728       left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2729       if (GET_CODE (left) == NOT)
2730 	return XEXP (left, 0);
2731 
2732       if (left == false_rtx)
2733 	return true_rtx;
2734       if (left == true_rtx)
2735 	return false_rtx;
2736 
2737       if (GET_CODE (left) == EQ_ATTR_ALT)
2738 	{
2739 	  exp = attr_alt_complement (left);
2740 	  return simplify_test_exp (exp, insn_code, insn_index);
2741 	}
2742 
2743       /* Try to apply De`Morgan's laws.  */
2744       if (GET_CODE (left) == IOR)
2745 	{
2746 	  newexp = attr_rtx (AND,
2747 			     attr_rtx (NOT, XEXP (left, 0)),
2748 			     attr_rtx (NOT, XEXP (left, 1)));
2749 
2750 	  newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2751 	}
2752       else if (GET_CODE (left) == AND)
2753 	{
2754 	  newexp = attr_rtx (IOR,
2755 			     attr_rtx (NOT, XEXP (left, 0)),
2756 			     attr_rtx (NOT, XEXP (left, 1)));
2757 
2758 	  newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2759 	}
2760       else if (left != XEXP (exp, 0))
2761 	{
2762 	  newexp = attr_rtx (NOT, left);
2763 	}
2764       break;
2765 
2766     case EQ_ATTR_ALT:
2767       if (!XINT (exp, 0))
2768 	return XINT (exp, 1) ? true_rtx : false_rtx;
2769       break;
2770 
2771     case EQ_ATTR:
2772       if (XSTR (exp, 0) == alternative_name)
2773 	{
2774 	  newexp = mk_attr_alt (1 << atoi (XSTR (exp, 1)));
2775 	  break;
2776 	}
2777 
2778       /* Look at the value for this insn code in the specified attribute.
2779 	 We normally can replace this comparison with the condition that
2780 	 would give this insn the values being tested for.  */
2781       if (insn_code >= 0
2782 	  && (attr = find_attr (&XSTR (exp, 0), 0)) != NULL)
2783 	for (av = attr->first_value; av; av = av->next)
2784 	  for (ie = av->first_insn; ie; ie = ie->next)
2785 	    if (ie->def->insn_code == insn_code)
2786 	      {
2787 		rtx x;
2788 		x = evaluate_eq_attr (exp, av->value, insn_code, insn_index);
2789 		x = SIMPLIFY_TEST_EXP (x, insn_code, insn_index);
2790 		if (attr_rtx_cost(x) < 20)
2791 		  return x;
2792 	      }
2793       break;
2794 
2795     default:
2796       break;
2797     }
2798 
2799   /* We have already simplified this expression.  Simplifying it again
2800      won't buy anything unless we weren't given a valid insn code
2801      to process (i.e., we are canonicalizing something.).  */
2802   if (insn_code != -2
2803       && ! ATTR_IND_SIMPLIFIED_P (newexp))
2804     return copy_rtx_unchanging (newexp);
2805 
2806   return newexp;
2807 }
2808 
2809 /* Optimize the attribute lists by seeing if we can determine conditional
2810    values from the known values of other attributes.  This will save subroutine
2811    calls during the compilation.  */
2812 
2813 static void
optimize_attrs(void)2814 optimize_attrs (void)
2815 {
2816   struct attr_desc *attr;
2817   struct attr_value *av;
2818   struct insn_ent *ie;
2819   rtx newexp;
2820   int i;
2821   struct attr_value_list
2822   {
2823     struct attr_value *av;
2824     struct insn_ent *ie;
2825     struct attr_desc *attr;
2826     struct attr_value_list *next;
2827   };
2828   struct attr_value_list **insn_code_values;
2829   struct attr_value_list *ivbuf;
2830   struct attr_value_list *iv;
2831 
2832   /* For each insn code, make a list of all the insn_ent's for it,
2833      for all values for all attributes.  */
2834 
2835   if (num_insn_ents == 0)
2836     return;
2837 
2838   /* Make 2 extra elements, for "code" values -2 and -1.  */
2839   insn_code_values = xcalloc ((insn_code_number + 2),
2840 			      sizeof (struct attr_value_list *));
2841 
2842   /* Offset the table address so we can index by -2 or -1.  */
2843   insn_code_values += 2;
2844 
2845   iv = ivbuf = xmalloc (num_insn_ents * sizeof (struct attr_value_list));
2846 
2847   for (i = 0; i < MAX_ATTRS_INDEX; i++)
2848     for (attr = attrs[i]; attr; attr = attr->next)
2849       for (av = attr->first_value; av; av = av->next)
2850 	for (ie = av->first_insn; ie; ie = ie->next)
2851 	  {
2852 	    iv->attr = attr;
2853 	    iv->av = av;
2854 	    iv->ie = ie;
2855 	    iv->next = insn_code_values[ie->def->insn_code];
2856 	    insn_code_values[ie->def->insn_code] = iv;
2857 	    iv++;
2858 	  }
2859 
2860   /* Sanity check on num_insn_ents.  */
2861   gcc_assert (iv == ivbuf + num_insn_ents);
2862 
2863   /* Process one insn code at a time.  */
2864   for (i = -2; i < insn_code_number; i++)
2865     {
2866       /* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere relevant.
2867 	 We use it to mean "already simplified for this insn".  */
2868       for (iv = insn_code_values[i]; iv; iv = iv->next)
2869 	clear_struct_flag (iv->av->value);
2870 
2871       for (iv = insn_code_values[i]; iv; iv = iv->next)
2872 	{
2873 	  struct obstack *old = rtl_obstack;
2874 
2875 	  attr = iv->attr;
2876 	  av = iv->av;
2877 	  ie = iv->ie;
2878 	  if (GET_CODE (av->value) != COND)
2879 	    continue;
2880 
2881 	  rtl_obstack = temp_obstack;
2882 	  newexp = av->value;
2883 	  while (GET_CODE (newexp) == COND)
2884 	    {
2885 	      rtx newexp2 = simplify_cond (newexp, ie->def->insn_code,
2886 					   ie->def->insn_index);
2887 	      if (newexp2 == newexp)
2888 		break;
2889 	      newexp = newexp2;
2890 	    }
2891 
2892 	  rtl_obstack = old;
2893 	  if (newexp != av->value)
2894 	    {
2895 	      newexp = attr_copy_rtx (newexp);
2896 	      remove_insn_ent (av, ie);
2897 	      av = get_attr_value (newexp, attr, ie->def->insn_code);
2898 	      iv->av = av;
2899 	      insert_insn_ent (av, ie);
2900 	    }
2901 	}
2902     }
2903 
2904   free (ivbuf);
2905   free (insn_code_values - 2);
2906 }
2907 
2908 /* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions.  */
2909 
2910 static void
clear_struct_flag(rtx x)2911 clear_struct_flag (rtx x)
2912 {
2913   int i;
2914   int j;
2915   enum rtx_code code;
2916   const char *fmt;
2917 
2918   ATTR_CURR_SIMPLIFIED_P (x) = 0;
2919   if (ATTR_IND_SIMPLIFIED_P (x))
2920     return;
2921 
2922   code = GET_CODE (x);
2923 
2924   switch (code)
2925     {
2926     case REG:
2927     case CONST_INT:
2928     case CONST_DOUBLE:
2929     case CONST_VECTOR:
2930     case SYMBOL_REF:
2931     case CODE_LABEL:
2932     case PC:
2933     case CC0:
2934     case EQ_ATTR:
2935     case ATTR_FLAG:
2936       return;
2937 
2938     default:
2939       break;
2940     }
2941 
2942   /* Compare the elements.  If any pair of corresponding elements
2943      fail to match, return 0 for the whole things.  */
2944 
2945   fmt = GET_RTX_FORMAT (code);
2946   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
2947     {
2948       switch (fmt[i])
2949 	{
2950 	case 'V':
2951 	case 'E':
2952 	  for (j = 0; j < XVECLEN (x, i); j++)
2953 	    clear_struct_flag (XVECEXP (x, i, j));
2954 	  break;
2955 
2956 	case 'e':
2957 	  clear_struct_flag (XEXP (x, i));
2958 	  break;
2959 	}
2960     }
2961 }
2962 
2963 /* Create table entries for DEFINE_ATTR.  */
2964 
2965 static void
gen_attr(rtx exp,int lineno)2966 gen_attr (rtx exp, int lineno)
2967 {
2968   struct attr_desc *attr;
2969   struct attr_value *av;
2970   const char *name_ptr;
2971   char *p;
2972 
2973   /* Make a new attribute structure.  Check for duplicate by looking at
2974      attr->default_val, since it is initialized by this routine.  */
2975   attr = find_attr (&XSTR (exp, 0), 1);
2976   if (attr->default_val)
2977     {
2978       message_with_line (lineno, "duplicate definition for attribute %s",
2979 			 attr->name);
2980       message_with_line (attr->lineno, "previous definition");
2981       have_error = 1;
2982       return;
2983     }
2984   attr->lineno = lineno;
2985 
2986   if (*XSTR (exp, 1) == '\0')
2987     attr->is_numeric = 1;
2988   else
2989     {
2990       name_ptr = XSTR (exp, 1);
2991       while ((p = next_comma_elt (&name_ptr)) != NULL)
2992 	{
2993 	  av = oballoc (sizeof (struct attr_value));
2994 	  av->value = attr_rtx (CONST_STRING, p);
2995 	  av->next = attr->first_value;
2996 	  attr->first_value = av;
2997 	  av->first_insn = NULL;
2998 	  av->num_insns = 0;
2999 	  av->has_asm_insn = 0;
3000 	}
3001     }
3002 
3003   if (GET_CODE (XEXP (exp, 2)) == CONST)
3004     {
3005       attr->is_const = 1;
3006       if (attr->is_numeric)
3007 	{
3008 	  message_with_line (lineno,
3009 			     "constant attributes may not take numeric values");
3010 	  have_error = 1;
3011 	}
3012 
3013       /* Get rid of the CONST node.  It is allowed only at top-level.  */
3014       XEXP (exp, 2) = XEXP (XEXP (exp, 2), 0);
3015     }
3016 
3017   if (! strcmp_check (attr->name, length_str) && ! attr->is_numeric)
3018     {
3019       message_with_line (lineno,
3020 			 "`length' attribute must take numeric values");
3021       have_error = 1;
3022     }
3023 
3024   /* Set up the default value.  */
3025   XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
3026   attr->default_val = get_attr_value (XEXP (exp, 2), attr, -2);
3027 }
3028 
3029 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
3030    alternatives in the constraints.  Assume all MATCH_OPERANDs have the same
3031    number of alternatives as this should be checked elsewhere.  */
3032 
3033 static int
count_alternatives(rtx exp)3034 count_alternatives (rtx exp)
3035 {
3036   int i, j, n;
3037   const char *fmt;
3038 
3039   if (GET_CODE (exp) == MATCH_OPERAND)
3040     return n_comma_elts (XSTR (exp, 2));
3041 
3042   for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
3043        i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
3044     switch (*fmt++)
3045       {
3046       case 'e':
3047       case 'u':
3048 	n = count_alternatives (XEXP (exp, i));
3049 	if (n)
3050 	  return n;
3051 	break;
3052 
3053       case 'E':
3054       case 'V':
3055 	if (XVEC (exp, i) != NULL)
3056 	  for (j = 0; j < XVECLEN (exp, i); j++)
3057 	    {
3058 	      n = count_alternatives (XVECEXP (exp, i, j));
3059 	      if (n)
3060 		return n;
3061 	    }
3062       }
3063 
3064   return 0;
3065 }
3066 
3067 /* Returns nonzero if the given expression contains an EQ_ATTR with the
3068    `alternative' attribute.  */
3069 
3070 static int
compares_alternatives_p(rtx exp)3071 compares_alternatives_p (rtx exp)
3072 {
3073   int i, j;
3074   const char *fmt;
3075 
3076   if (GET_CODE (exp) == EQ_ATTR && XSTR (exp, 0) == alternative_name)
3077     return 1;
3078 
3079   for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
3080        i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
3081     switch (*fmt++)
3082       {
3083       case 'e':
3084       case 'u':
3085 	if (compares_alternatives_p (XEXP (exp, i)))
3086 	  return 1;
3087 	break;
3088 
3089       case 'E':
3090 	for (j = 0; j < XVECLEN (exp, i); j++)
3091 	  if (compares_alternatives_p (XVECEXP (exp, i, j)))
3092 	    return 1;
3093 	break;
3094       }
3095 
3096   return 0;
3097 }
3098 
3099 /* Returns nonzero is INNER is contained in EXP.  */
3100 
3101 static int
contained_in_p(rtx inner,rtx exp)3102 contained_in_p (rtx inner, rtx exp)
3103 {
3104   int i, j;
3105   const char *fmt;
3106 
3107   if (rtx_equal_p (inner, exp))
3108     return 1;
3109 
3110   for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
3111        i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
3112     switch (*fmt++)
3113       {
3114       case 'e':
3115       case 'u':
3116 	if (contained_in_p (inner, XEXP (exp, i)))
3117 	  return 1;
3118 	break;
3119 
3120       case 'E':
3121 	for (j = 0; j < XVECLEN (exp, i); j++)
3122 	  if (contained_in_p (inner, XVECEXP (exp, i, j)))
3123 	    return 1;
3124 	break;
3125       }
3126 
3127   return 0;
3128 }
3129 
3130 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES.  */
3131 
3132 static void
gen_insn(rtx exp,int lineno)3133 gen_insn (rtx exp, int lineno)
3134 {
3135   struct insn_def *id;
3136 
3137   id = oballoc (sizeof (struct insn_def));
3138   id->next = defs;
3139   defs = id;
3140   id->def = exp;
3141   id->lineno = lineno;
3142 
3143   switch (GET_CODE (exp))
3144     {
3145     case DEFINE_INSN:
3146       id->insn_code = insn_code_number;
3147       id->insn_index = insn_index_number;
3148       id->num_alternatives = count_alternatives (exp);
3149       if (id->num_alternatives == 0)
3150 	id->num_alternatives = 1;
3151       id->vec_idx = 4;
3152       break;
3153 
3154     case DEFINE_PEEPHOLE:
3155       id->insn_code = insn_code_number;
3156       id->insn_index = insn_index_number;
3157       id->num_alternatives = count_alternatives (exp);
3158       if (id->num_alternatives == 0)
3159 	id->num_alternatives = 1;
3160       id->vec_idx = 3;
3161       break;
3162 
3163     case DEFINE_ASM_ATTRIBUTES:
3164       id->insn_code = -1;
3165       id->insn_index = -1;
3166       id->num_alternatives = 1;
3167       id->vec_idx = 0;
3168       got_define_asm_attributes = 1;
3169       break;
3170 
3171     default:
3172       gcc_unreachable ();
3173     }
3174 }
3175 
3176 /* Process a DEFINE_DELAY.  Validate the vector length, check if annul
3177    true or annul false is specified, and make a `struct delay_desc'.  */
3178 
3179 static void
gen_delay(rtx def,int lineno)3180 gen_delay (rtx def, int lineno)
3181 {
3182   struct delay_desc *delay;
3183   int i;
3184 
3185   if (XVECLEN (def, 1) % 3 != 0)
3186     {
3187       message_with_line (lineno,
3188 			 "number of elements in DEFINE_DELAY must be multiple of three");
3189       have_error = 1;
3190       return;
3191     }
3192 
3193   for (i = 0; i < XVECLEN (def, 1); i += 3)
3194     {
3195       if (XVECEXP (def, 1, i + 1))
3196 	have_annul_true = 1;
3197       if (XVECEXP (def, 1, i + 2))
3198 	have_annul_false = 1;
3199     }
3200 
3201   delay = oballoc (sizeof (struct delay_desc));
3202   delay->def = def;
3203   delay->num = ++num_delays;
3204   delay->next = delays;
3205   delay->lineno = lineno;
3206   delays = delay;
3207 }
3208 
3209 /* Given a piece of RTX, print a C expression to test its truth value.
3210    We use AND and IOR both for logical and bit-wise operations, so
3211    interpret them as logical unless they are inside a comparison expression.
3212    The first bit of FLAGS will be nonzero in that case.
3213 
3214    Set the second bit of FLAGS to make references to attribute values use
3215    a cached local variable instead of calling a function.  */
3216 
3217 static void
write_test_expr(rtx exp,int flags)3218 write_test_expr (rtx exp, int flags)
3219 {
3220   int comparison_operator = 0;
3221   RTX_CODE code;
3222   struct attr_desc *attr;
3223 
3224   /* In order not to worry about operator precedence, surround our part of
3225      the expression with parentheses.  */
3226 
3227   printf ("(");
3228   code = GET_CODE (exp);
3229   switch (code)
3230     {
3231     /* Binary operators.  */
3232     case GEU: case GTU:
3233     case LEU: case LTU:
3234       printf ("(unsigned) ");
3235       /* Fall through.  */
3236 
3237     case EQ: case NE:
3238     case GE: case GT:
3239     case LE: case LT:
3240       comparison_operator = 1;
3241 
3242     case PLUS:   case MINUS:  case MULT:     case DIV:      case MOD:
3243     case AND:    case IOR:    case XOR:
3244     case ASHIFT: case LSHIFTRT: case ASHIFTRT:
3245       write_test_expr (XEXP (exp, 0), flags | comparison_operator);
3246       switch (code)
3247 	{
3248 	case EQ:
3249 	  printf (" == ");
3250 	  break;
3251 	case NE:
3252 	  printf (" != ");
3253 	  break;
3254 	case GE:
3255 	  printf (" >= ");
3256 	  break;
3257 	case GT:
3258 	  printf (" > ");
3259 	  break;
3260 	case GEU:
3261 	  printf (" >= (unsigned) ");
3262 	  break;
3263 	case GTU:
3264 	  printf (" > (unsigned) ");
3265 	  break;
3266 	case LE:
3267 	  printf (" <= ");
3268 	  break;
3269 	case LT:
3270 	  printf (" < ");
3271 	  break;
3272 	case LEU:
3273 	  printf (" <= (unsigned) ");
3274 	  break;
3275 	case LTU:
3276 	  printf (" < (unsigned) ");
3277 	  break;
3278 	case PLUS:
3279 	  printf (" + ");
3280 	  break;
3281 	case MINUS:
3282 	  printf (" - ");
3283 	  break;
3284 	case MULT:
3285 	  printf (" * ");
3286 	  break;
3287 	case DIV:
3288 	  printf (" / ");
3289 	  break;
3290 	case MOD:
3291 	  printf (" %% ");
3292 	  break;
3293 	case AND:
3294 	  if (flags & 1)
3295 	    printf (" & ");
3296 	  else
3297 	    printf (" && ");
3298 	  break;
3299 	case IOR:
3300 	  if (flags & 1)
3301 	    printf (" | ");
3302 	  else
3303 	    printf (" || ");
3304 	  break;
3305 	case XOR:
3306 	  printf (" ^ ");
3307 	  break;
3308 	case ASHIFT:
3309 	  printf (" << ");
3310 	  break;
3311 	case LSHIFTRT:
3312 	case ASHIFTRT:
3313 	  printf (" >> ");
3314 	  break;
3315 	default:
3316 	  gcc_unreachable ();
3317 	}
3318 
3319       write_test_expr (XEXP (exp, 1), flags | comparison_operator);
3320       break;
3321 
3322     case NOT:
3323       /* Special-case (not (eq_attrq "alternative" "x")) */
3324       if (! (flags & 1) && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
3325 	  && XSTR (XEXP (exp, 0), 0) == alternative_name)
3326 	{
3327 	  printf ("which_alternative != %s", XSTR (XEXP (exp, 0), 1));
3328 	  break;
3329 	}
3330 
3331       /* Otherwise, fall through to normal unary operator.  */
3332 
3333     /* Unary operators.  */
3334     case ABS:  case NEG:
3335       switch (code)
3336 	{
3337 	case NOT:
3338 	  if (flags & 1)
3339 	    printf ("~ ");
3340 	  else
3341 	    printf ("! ");
3342 	  break;
3343 	case ABS:
3344 	  printf ("abs ");
3345 	  break;
3346 	case NEG:
3347 	  printf ("-");
3348 	  break;
3349 	default:
3350 	  gcc_unreachable ();
3351 	}
3352 
3353       write_test_expr (XEXP (exp, 0), flags);
3354       break;
3355 
3356     case EQ_ATTR_ALT:
3357 	{
3358 	  int set = XINT (exp, 0), bit = 0;
3359 
3360 	  if (flags & 1)
3361 	    fatal ("EQ_ATTR_ALT not valid inside comparison");
3362 
3363 	  if (!set)
3364 	    fatal ("Empty EQ_ATTR_ALT should be optimized out");
3365 
3366 	  if (!(set & (set - 1)))
3367 	    {
3368 	      if (!(set & 0xffff))
3369 		{
3370 		  bit += 16;
3371 		  set >>= 16;
3372 		}
3373 	      if (!(set & 0xff))
3374 		{
3375 		  bit += 8;
3376 		  set >>= 8;
3377 		}
3378 	      if (!(set & 0xf))
3379 		{
3380 		  bit += 4;
3381 		  set >>= 4;
3382 		}
3383 	      if (!(set & 0x3))
3384 		{
3385 		  bit += 2;
3386 		  set >>= 2;
3387 		}
3388 	      if (!(set & 1))
3389 		bit++;
3390 
3391 	      printf ("which_alternative %s= %d",
3392 		      XINT (exp, 1) ? "!" : "=", bit);
3393 	    }
3394 	  else
3395 	    {
3396 	      printf ("%s((1 << which_alternative) & 0x%x)",
3397 		      XINT (exp, 1) ? "!" : "", set);
3398 	    }
3399 	}
3400       break;
3401 
3402     /* Comparison test of an attribute with a value.  Most of these will
3403        have been removed by optimization.   Handle "alternative"
3404        specially and give error if EQ_ATTR present inside a comparison.  */
3405     case EQ_ATTR:
3406       if (flags & 1)
3407 	fatal ("EQ_ATTR not valid inside comparison");
3408 
3409       if (XSTR (exp, 0) == alternative_name)
3410 	{
3411 	  printf ("which_alternative == %s", XSTR (exp, 1));
3412 	  break;
3413 	}
3414 
3415       attr = find_attr (&XSTR (exp, 0), 0);
3416       gcc_assert (attr);
3417 
3418       /* Now is the time to expand the value of a constant attribute.  */
3419       if (attr->is_const)
3420 	{
3421 	  write_test_expr (evaluate_eq_attr (exp, attr->default_val->value,
3422 					     -2, -2),
3423 			   flags);
3424 	}
3425       else
3426 	{
3427 	  if (flags & 2)
3428 	    printf ("attr_%s", attr->name);
3429 	  else
3430 	    printf ("get_attr_%s (insn)", attr->name);
3431 	  printf (" == ");
3432 	  write_attr_valueq (attr, XSTR (exp, 1));
3433 	}
3434       break;
3435 
3436     /* Comparison test of flags for define_delays.  */
3437     case ATTR_FLAG:
3438       if (flags & 1)
3439 	fatal ("ATTR_FLAG not valid inside comparison");
3440       printf ("(flags & ATTR_FLAG_%s) != 0", XSTR (exp, 0));
3441       break;
3442 
3443     /* See if an operand matches a predicate.  */
3444     case MATCH_OPERAND:
3445       /* If only a mode is given, just ensure the mode matches the operand.
3446 	 If neither a mode nor predicate is given, error.  */
3447       if (XSTR (exp, 1) == NULL || *XSTR (exp, 1) == '\0')
3448 	{
3449 	  if (GET_MODE (exp) == VOIDmode)
3450 	    fatal ("null MATCH_OPERAND specified as test");
3451 	  else
3452 	    printf ("GET_MODE (operands[%d]) == %smode",
3453 		    XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
3454 	}
3455       else
3456 	printf ("%s (operands[%d], %smode)",
3457 		XSTR (exp, 1), XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
3458       break;
3459 
3460     /* Constant integer.  */
3461     case CONST_INT:
3462       printf (HOST_WIDE_INT_PRINT_DEC, XWINT (exp, 0));
3463       break;
3464 
3465     /* A random C expression.  */
3466     case SYMBOL_REF:
3467       print_c_condition (XSTR (exp, 0));
3468       break;
3469 
3470     /* The address of the branch target.  */
3471     case MATCH_DUP:
3472       printf ("INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
3473 	      XINT (exp, 0), XINT (exp, 0), XINT (exp, 0));
3474       break;
3475 
3476     case PC:
3477       /* The address of the current insn.  We implement this actually as the
3478 	 address of the current insn for backward branches, but the last
3479 	 address of the next insn for forward branches, and both with
3480 	 adjustments that account for the worst-case possible stretching of
3481 	 intervening alignments between this insn and its destination.  */
3482       printf ("insn_current_reference_address (insn)");
3483       break;
3484 
3485     case CONST_STRING:
3486       printf ("%s", XSTR (exp, 0));
3487       break;
3488 
3489     case IF_THEN_ELSE:
3490       write_test_expr (XEXP (exp, 0), flags & 2);
3491       printf (" ? ");
3492       write_test_expr (XEXP (exp, 1), flags | 1);
3493       printf (" : ");
3494       write_test_expr (XEXP (exp, 2), flags | 1);
3495       break;
3496 
3497     default:
3498       fatal ("bad RTX code `%s' in attribute calculation\n",
3499 	     GET_RTX_NAME (code));
3500     }
3501 
3502   printf (")");
3503 }
3504 
3505 /* Given an attribute value, return the maximum CONST_STRING argument
3506    encountered.  Set *UNKNOWNP and return INT_MAX if the value is unknown.  */
3507 
3508 static int
max_attr_value(rtx exp,int * unknownp)3509 max_attr_value (rtx exp, int *unknownp)
3510 {
3511   int current_max;
3512   int i, n;
3513 
3514   switch (GET_CODE (exp))
3515     {
3516     case CONST_STRING:
3517       current_max = atoi (XSTR (exp, 0));
3518       break;
3519 
3520     case COND:
3521       current_max = max_attr_value (XEXP (exp, 1), unknownp);
3522       for (i = 0; i < XVECLEN (exp, 0); i += 2)
3523 	{
3524 	  n = max_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
3525 	  if (n > current_max)
3526 	    current_max = n;
3527 	}
3528       break;
3529 
3530     case IF_THEN_ELSE:
3531       current_max = max_attr_value (XEXP (exp, 1), unknownp);
3532       n = max_attr_value (XEXP (exp, 2), unknownp);
3533       if (n > current_max)
3534 	current_max = n;
3535       break;
3536 
3537     default:
3538       *unknownp = 1;
3539       current_max = INT_MAX;
3540       break;
3541     }
3542 
3543   return current_max;
3544 }
3545 
3546 /* Given an attribute value, return the minimum CONST_STRING argument
3547    encountered.  Set *UNKNOWNP and return 0 if the value is unknown.  */
3548 
3549 static int
min_attr_value(rtx exp,int * unknownp)3550 min_attr_value (rtx exp, int *unknownp)
3551 {
3552   int current_min;
3553   int i, n;
3554 
3555   switch (GET_CODE (exp))
3556     {
3557     case CONST_STRING:
3558       current_min = atoi (XSTR (exp, 0));
3559       break;
3560 
3561     case COND:
3562       current_min = min_attr_value (XEXP (exp, 1), unknownp);
3563       for (i = 0; i < XVECLEN (exp, 0); i += 2)
3564 	{
3565 	  n = min_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
3566 	  if (n < current_min)
3567 	    current_min = n;
3568 	}
3569       break;
3570 
3571     case IF_THEN_ELSE:
3572       current_min = min_attr_value (XEXP (exp, 1), unknownp);
3573       n = min_attr_value (XEXP (exp, 2), unknownp);
3574       if (n < current_min)
3575 	current_min = n;
3576       break;
3577 
3578     default:
3579       *unknownp = 1;
3580       current_min = INT_MAX;
3581       break;
3582     }
3583 
3584   return current_min;
3585 }
3586 
3587 /* Given an attribute value, return the result of ORing together all
3588    CONST_STRING arguments encountered.  Set *UNKNOWNP and return -1
3589    if the numeric value is not known.  */
3590 
3591 static int
or_attr_value(rtx exp,int * unknownp)3592 or_attr_value (rtx exp, int *unknownp)
3593 {
3594   int current_or;
3595   int i;
3596 
3597   switch (GET_CODE (exp))
3598     {
3599     case CONST_STRING:
3600       current_or = atoi (XSTR (exp, 0));
3601       break;
3602 
3603     case COND:
3604       current_or = or_attr_value (XEXP (exp, 1), unknownp);
3605       for (i = 0; i < XVECLEN (exp, 0); i += 2)
3606 	current_or |= or_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
3607       break;
3608 
3609     case IF_THEN_ELSE:
3610       current_or = or_attr_value (XEXP (exp, 1), unknownp);
3611       current_or |= or_attr_value (XEXP (exp, 2), unknownp);
3612       break;
3613 
3614     default:
3615       *unknownp = 1;
3616       current_or = -1;
3617       break;
3618     }
3619 
3620   return current_or;
3621 }
3622 
3623 /* Scan an attribute value, possibly a conditional, and record what actions
3624    will be required to do any conditional tests in it.
3625 
3626    Specifically, set
3627 	`must_extract'	  if we need to extract the insn operands
3628 	`must_constrain'  if we must compute `which_alternative'
3629 	`address_used'	  if an address expression was used
3630 	`length_used'	  if an (eq_attr "length" ...) was used
3631  */
3632 
3633 static void
walk_attr_value(rtx exp)3634 walk_attr_value (rtx exp)
3635 {
3636   int i, j;
3637   const char *fmt;
3638   RTX_CODE code;
3639 
3640   if (exp == NULL)
3641     return;
3642 
3643   code = GET_CODE (exp);
3644   switch (code)
3645     {
3646     case SYMBOL_REF:
3647       if (! ATTR_IND_SIMPLIFIED_P (exp))
3648 	/* Since this is an arbitrary expression, it can look at anything.
3649 	   However, constant expressions do not depend on any particular
3650 	   insn.  */
3651 	must_extract = must_constrain = 1;
3652       return;
3653 
3654     case MATCH_OPERAND:
3655       must_extract = 1;
3656       return;
3657 
3658     case EQ_ATTR_ALT:
3659       must_extract = must_constrain = 1;
3660       break;
3661 
3662     case EQ_ATTR:
3663       if (XSTR (exp, 0) == alternative_name)
3664 	must_extract = must_constrain = 1;
3665       else if (strcmp_check (XSTR (exp, 0), length_str) == 0)
3666 	length_used = 1;
3667       return;
3668 
3669     case MATCH_DUP:
3670       must_extract = 1;
3671       address_used = 1;
3672       return;
3673 
3674     case PC:
3675       address_used = 1;
3676       return;
3677 
3678     case ATTR_FLAG:
3679       return;
3680 
3681     default:
3682       break;
3683     }
3684 
3685   for (i = 0, fmt = GET_RTX_FORMAT (code); i < GET_RTX_LENGTH (code); i++)
3686     switch (*fmt++)
3687       {
3688       case 'e':
3689       case 'u':
3690 	walk_attr_value (XEXP (exp, i));
3691 	break;
3692 
3693       case 'E':
3694 	if (XVEC (exp, i) != NULL)
3695 	  for (j = 0; j < XVECLEN (exp, i); j++)
3696 	    walk_attr_value (XVECEXP (exp, i, j));
3697 	break;
3698       }
3699 }
3700 
3701 /* Write out a function to obtain the attribute for a given INSN.  */
3702 
3703 static void
write_attr_get(struct attr_desc * attr)3704 write_attr_get (struct attr_desc *attr)
3705 {
3706   struct attr_value *av, *common_av;
3707 
3708   /* Find the most used attribute value.  Handle that as the `default' of the
3709      switch we will generate.  */
3710   common_av = find_most_used (attr);
3711 
3712   /* Write out start of function, then all values with explicit `case' lines,
3713      then a `default', then the value with the most uses.  */
3714   if (attr->static_p)
3715     printf ("static ");
3716   if (!attr->is_numeric)
3717     printf ("enum attr_%s\n", attr->name);
3718   else
3719     printf ("int\n");
3720 
3721   /* If the attribute name starts with a star, the remainder is the name of
3722      the subroutine to use, instead of `get_attr_...'.  */
3723   if (attr->name[0] == '*')
3724     printf ("%s (rtx insn ATTRIBUTE_UNUSED)\n", &attr->name[1]);
3725   else if (attr->is_const == 0)
3726     printf ("get_attr_%s (rtx insn ATTRIBUTE_UNUSED)\n", attr->name);
3727   else
3728     {
3729       printf ("get_attr_%s (void)\n", attr->name);
3730       printf ("{\n");
3731 
3732       for (av = attr->first_value; av; av = av->next)
3733 	if (av->num_insns == 1)
3734 	  write_attr_set (attr, 2, av->value, "return", ";",
3735 			  true_rtx, av->first_insn->def->insn_code,
3736 			  av->first_insn->def->insn_index);
3737 	else if (av->num_insns != 0)
3738 	  write_attr_set (attr, 2, av->value, "return", ";",
3739 			  true_rtx, -2, 0);
3740 
3741       printf ("}\n\n");
3742       return;
3743     }
3744 
3745   printf ("{\n");
3746   printf ("  switch (recog_memoized (insn))\n");
3747   printf ("    {\n");
3748 
3749   for (av = attr->first_value; av; av = av->next)
3750     if (av != common_av)
3751       write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
3752 
3753   write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
3754   printf ("    }\n}\n\n");
3755 }
3756 
3757 /* Given an AND tree of known true terms (because we are inside an `if' with
3758    that as the condition or are in an `else' clause) and an expression,
3759    replace any known true terms with TRUE.  Use `simplify_and_tree' to do
3760    the bulk of the work.  */
3761 
3762 static rtx
eliminate_known_true(rtx known_true,rtx exp,int insn_code,int insn_index)3763 eliminate_known_true (rtx known_true, rtx exp, int insn_code, int insn_index)
3764 {
3765   rtx term;
3766 
3767   known_true = SIMPLIFY_TEST_EXP (known_true, insn_code, insn_index);
3768 
3769   if (GET_CODE (known_true) == AND)
3770     {
3771       exp = eliminate_known_true (XEXP (known_true, 0), exp,
3772 				  insn_code, insn_index);
3773       exp = eliminate_known_true (XEXP (known_true, 1), exp,
3774 				  insn_code, insn_index);
3775     }
3776   else
3777     {
3778       term = known_true;
3779       exp = simplify_and_tree (exp, &term, insn_code, insn_index);
3780     }
3781 
3782   return exp;
3783 }
3784 
3785 /* Write out a series of tests and assignment statements to perform tests and
3786    sets of an attribute value.  We are passed an indentation amount and prefix
3787    and suffix strings to write around each attribute value (e.g., "return"
3788    and ";").  */
3789 
3790 static void
write_attr_set(struct attr_desc * attr,int indent,rtx value,const char * prefix,const char * suffix,rtx known_true,int insn_code,int insn_index)3791 write_attr_set (struct attr_desc *attr, int indent, rtx value,
3792 		const char *prefix, const char *suffix, rtx known_true,
3793 		int insn_code, int insn_index)
3794 {
3795   if (GET_CODE (value) == COND)
3796     {
3797       /* Assume the default value will be the default of the COND unless we
3798 	 find an always true expression.  */
3799       rtx default_val = XEXP (value, 1);
3800       rtx our_known_true = known_true;
3801       rtx newexp;
3802       int first_if = 1;
3803       int i;
3804 
3805       for (i = 0; i < XVECLEN (value, 0); i += 2)
3806 	{
3807 	  rtx testexp;
3808 	  rtx inner_true;
3809 
3810 	  testexp = eliminate_known_true (our_known_true,
3811 					  XVECEXP (value, 0, i),
3812 					  insn_code, insn_index);
3813 	  newexp = attr_rtx (NOT, testexp);
3814 	  newexp = insert_right_side (AND, our_known_true, newexp,
3815 				      insn_code, insn_index);
3816 
3817 	  /* If the test expression is always true or if the next `known_true'
3818 	     expression is always false, this is the last case, so break
3819 	     out and let this value be the `else' case.  */
3820 	  if (testexp == true_rtx || newexp == false_rtx)
3821 	    {
3822 	      default_val = XVECEXP (value, 0, i + 1);
3823 	      break;
3824 	    }
3825 
3826 	  /* Compute the expression to pass to our recursive call as being
3827 	     known true.  */
3828 	  inner_true = insert_right_side (AND, our_known_true,
3829 					  testexp, insn_code, insn_index);
3830 
3831 	  /* If this is always false, skip it.  */
3832 	  if (inner_true == false_rtx)
3833 	    continue;
3834 
3835 	  write_indent (indent);
3836 	  printf ("%sif ", first_if ? "" : "else ");
3837 	  first_if = 0;
3838 	  write_test_expr (testexp, 0);
3839 	  printf ("\n");
3840 	  write_indent (indent + 2);
3841 	  printf ("{\n");
3842 
3843 	  write_attr_set (attr, indent + 4,
3844 			  XVECEXP (value, 0, i + 1), prefix, suffix,
3845 			  inner_true, insn_code, insn_index);
3846 	  write_indent (indent + 2);
3847 	  printf ("}\n");
3848 	  our_known_true = newexp;
3849 	}
3850 
3851       if (! first_if)
3852 	{
3853 	  write_indent (indent);
3854 	  printf ("else\n");
3855 	  write_indent (indent + 2);
3856 	  printf ("{\n");
3857 	}
3858 
3859       write_attr_set (attr, first_if ? indent : indent + 4, default_val,
3860 		      prefix, suffix, our_known_true, insn_code, insn_index);
3861 
3862       if (! first_if)
3863 	{
3864 	  write_indent (indent + 2);
3865 	  printf ("}\n");
3866 	}
3867     }
3868   else
3869     {
3870       write_indent (indent);
3871       printf ("%s ", prefix);
3872       write_attr_value (attr, value);
3873       printf ("%s\n", suffix);
3874     }
3875 }
3876 
3877 /* Write a series of case statements for every instruction in list IE.
3878    INDENT is the amount of indentation to write before each case.  */
3879 
3880 static void
write_insn_cases(struct insn_ent * ie,int indent)3881 write_insn_cases (struct insn_ent *ie, int indent)
3882 {
3883   for (; ie != 0; ie = ie->next)
3884     if (ie->def->insn_code != -1)
3885       {
3886 	write_indent (indent);
3887 	if (GET_CODE (ie->def->def) == DEFINE_PEEPHOLE)
3888 	  printf ("case %d:  /* define_peephole, line %d */\n",
3889 		  ie->def->insn_code, ie->def->lineno);
3890 	else
3891 	  printf ("case %d:  /* %s */\n",
3892 		  ie->def->insn_code, XSTR (ie->def->def, 0));
3893       }
3894 }
3895 
3896 /* Write out the computation for one attribute value.  */
3897 
3898 static void
write_attr_case(struct attr_desc * attr,struct attr_value * av,int write_case_lines,const char * prefix,const char * suffix,int indent,rtx known_true)3899 write_attr_case (struct attr_desc *attr, struct attr_value *av,
3900 		 int write_case_lines, const char *prefix, const char *suffix,
3901 		 int indent, rtx known_true)
3902 {
3903   if (av->num_insns == 0)
3904     return;
3905 
3906   if (av->has_asm_insn)
3907     {
3908       write_indent (indent);
3909       printf ("case -1:\n");
3910       write_indent (indent + 2);
3911       printf ("if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
3912       write_indent (indent + 2);
3913       printf ("    && asm_noperands (PATTERN (insn)) < 0)\n");
3914       write_indent (indent + 2);
3915       printf ("  fatal_insn_not_found (insn);\n");
3916     }
3917 
3918   if (write_case_lines)
3919     write_insn_cases (av->first_insn, indent);
3920   else
3921     {
3922       write_indent (indent);
3923       printf ("default:\n");
3924     }
3925 
3926   /* See what we have to do to output this value.  */
3927   must_extract = must_constrain = address_used = 0;
3928   walk_attr_value (av->value);
3929 
3930   if (must_constrain)
3931     {
3932       write_indent (indent + 2);
3933       printf ("extract_constrain_insn_cached (insn);\n");
3934     }
3935   else if (must_extract)
3936     {
3937       write_indent (indent + 2);
3938       printf ("extract_insn_cached (insn);\n");
3939     }
3940 
3941   if (av->num_insns == 1)
3942     write_attr_set (attr, indent + 2, av->value, prefix, suffix,
3943 		    known_true, av->first_insn->def->insn_code,
3944 		    av->first_insn->def->insn_index);
3945   else
3946     write_attr_set (attr, indent + 2, av->value, prefix, suffix,
3947 		    known_true, -2, 0);
3948 
3949   if (strncmp (prefix, "return", 6))
3950     {
3951       write_indent (indent + 2);
3952       printf ("break;\n");
3953     }
3954   printf ("\n");
3955 }
3956 
3957 /* Search for uses of non-const attributes and write code to cache them.  */
3958 
3959 static int
write_expr_attr_cache(rtx p,struct attr_desc * attr)3960 write_expr_attr_cache (rtx p, struct attr_desc *attr)
3961 {
3962   const char *fmt;
3963   int i, ie, j, je;
3964 
3965   if (GET_CODE (p) == EQ_ATTR)
3966     {
3967       if (XSTR (p, 0) != attr->name)
3968 	return 0;
3969 
3970       if (!attr->is_numeric)
3971 	printf ("  enum attr_%s ", attr->name);
3972       else
3973 	printf ("  int ");
3974 
3975       printf ("attr_%s = get_attr_%s (insn);\n", attr->name, attr->name);
3976       return 1;
3977     }
3978 
3979   fmt = GET_RTX_FORMAT (GET_CODE (p));
3980   ie = GET_RTX_LENGTH (GET_CODE (p));
3981   for (i = 0; i < ie; i++)
3982     {
3983       switch (*fmt++)
3984 	{
3985 	case 'e':
3986 	  if (write_expr_attr_cache (XEXP (p, i), attr))
3987 	    return 1;
3988 	  break;
3989 
3990 	case 'E':
3991 	  je = XVECLEN (p, i);
3992 	  for (j = 0; j < je; ++j)
3993 	    if (write_expr_attr_cache (XVECEXP (p, i, j), attr))
3994 	      return 1;
3995 	  break;
3996 	}
3997     }
3998 
3999   return 0;
4000 }
4001 
4002 /* Utilities to write in various forms.  */
4003 
4004 static void
write_attr_valueq(struct attr_desc * attr,const char * s)4005 write_attr_valueq (struct attr_desc *attr, const char *s)
4006 {
4007   if (attr->is_numeric)
4008     {
4009       int num = atoi (s);
4010 
4011       printf ("%d", num);
4012 
4013       if (num > 9 || num < 0)
4014 	printf (" /* 0x%x */", num);
4015     }
4016   else
4017     {
4018       write_upcase (attr->name);
4019       printf ("_");
4020       write_upcase (s);
4021     }
4022 }
4023 
4024 static void
write_attr_value(struct attr_desc * attr,rtx value)4025 write_attr_value (struct attr_desc *attr, rtx value)
4026 {
4027   int op;
4028 
4029   switch (GET_CODE (value))
4030     {
4031     case CONST_STRING:
4032       write_attr_valueq (attr, XSTR (value, 0));
4033       break;
4034 
4035     case CONST_INT:
4036       printf (HOST_WIDE_INT_PRINT_DEC, INTVAL (value));
4037       break;
4038 
4039     case SYMBOL_REF:
4040       print_c_condition (XSTR (value, 0));
4041       break;
4042 
4043     case ATTR:
4044       {
4045 	struct attr_desc *attr2 = find_attr (&XSTR (value, 0), 0);
4046 	printf ("get_attr_%s (%s)", attr2->name,
4047 		(attr2->is_const ? "" : "insn"));
4048       }
4049       break;
4050 
4051     case PLUS:
4052       op = '+';
4053       goto do_operator;
4054     case MINUS:
4055       op = '-';
4056       goto do_operator;
4057     case MULT:
4058       op = '*';
4059       goto do_operator;
4060     case DIV:
4061       op = '/';
4062       goto do_operator;
4063     case MOD:
4064       op = '%';
4065       goto do_operator;
4066 
4067     do_operator:
4068       write_attr_value (attr, XEXP (value, 0));
4069       putchar (' ');
4070       putchar (op);
4071       putchar (' ');
4072       write_attr_value (attr, XEXP (value, 1));
4073       break;
4074 
4075     default:
4076       gcc_unreachable ();
4077     }
4078 }
4079 
4080 static void
write_upcase(const char * str)4081 write_upcase (const char *str)
4082 {
4083   while (*str)
4084     {
4085       /* The argument of TOUPPER should not have side effects.  */
4086       putchar (TOUPPER(*str));
4087       str++;
4088     }
4089 }
4090 
4091 static void
write_indent(int indent)4092 write_indent (int indent)
4093 {
4094   for (; indent > 8; indent -= 8)
4095     printf ("\t");
4096 
4097   for (; indent; indent--)
4098     printf (" ");
4099 }
4100 
4101 /* Write a subroutine that is given an insn that requires a delay slot, a
4102    delay slot ordinal, and a candidate insn.  It returns nonzero if the
4103    candidate can be placed in the specified delay slot of the insn.
4104 
4105    We can write as many as three subroutines.  `eligible_for_delay'
4106    handles normal delay slots, `eligible_for_annul_true' indicates that
4107    the specified insn can be annulled if the branch is true, and likewise
4108    for `eligible_for_annul_false'.
4109 
4110    KIND is a string distinguishing these three cases ("delay", "annul_true",
4111    or "annul_false").  */
4112 
4113 static void
write_eligible_delay(const char * kind)4114 write_eligible_delay (const char *kind)
4115 {
4116   struct delay_desc *delay;
4117   int max_slots;
4118   char str[50];
4119   const char *pstr;
4120   struct attr_desc *attr;
4121   struct attr_value *av, *common_av;
4122   int i;
4123 
4124   /* Compute the maximum number of delay slots required.  We use the delay
4125      ordinal times this number plus one, plus the slot number as an index into
4126      the appropriate predicate to test.  */
4127 
4128   for (delay = delays, max_slots = 0; delay; delay = delay->next)
4129     if (XVECLEN (delay->def, 1) / 3 > max_slots)
4130       max_slots = XVECLEN (delay->def, 1) / 3;
4131 
4132   /* Write function prelude.  */
4133 
4134   printf ("int\n");
4135   printf ("eligible_for_%s (rtx delay_insn ATTRIBUTE_UNUSED, int slot, rtx candidate_insn, int flags ATTRIBUTE_UNUSED)\n",
4136 	  kind);
4137   printf ("{\n");
4138   printf ("  rtx insn;\n");
4139   printf ("\n");
4140   printf ("  gcc_assert (slot < %d);\n", max_slots);
4141   printf ("\n");
4142   /* Allow dbr_schedule to pass labels, etc.  This can happen if try_split
4143      converts a compound instruction into a loop.  */
4144   printf ("  if (!INSN_P (candidate_insn))\n");
4145   printf ("    return 0;\n");
4146   printf ("\n");
4147 
4148   /* If more than one delay type, find out which type the delay insn is.  */
4149 
4150   if (num_delays > 1)
4151     {
4152       attr = find_attr (&delay_type_str, 0);
4153       gcc_assert (attr);
4154       common_av = find_most_used (attr);
4155 
4156       printf ("  insn = delay_insn;\n");
4157       printf ("  switch (recog_memoized (insn))\n");
4158       printf ("    {\n");
4159 
4160       sprintf (str, " * %d;\n      break;", max_slots);
4161       for (av = attr->first_value; av; av = av->next)
4162 	if (av != common_av)
4163 	  write_attr_case (attr, av, 1, "slot +=", str, 4, true_rtx);
4164 
4165       write_attr_case (attr, common_av, 0, "slot +=", str, 4, true_rtx);
4166       printf ("    }\n\n");
4167 
4168       /* Ensure matched.  Otherwise, shouldn't have been called.  */
4169       printf ("  gcc_assert (slot >= %d);\n\n", max_slots);
4170     }
4171 
4172   /* If just one type of delay slot, write simple switch.  */
4173   if (num_delays == 1 && max_slots == 1)
4174     {
4175       printf ("  insn = candidate_insn;\n");
4176       printf ("  switch (recog_memoized (insn))\n");
4177       printf ("    {\n");
4178 
4179       attr = find_attr (&delay_1_0_str, 0);
4180       gcc_assert (attr);
4181       common_av = find_most_used (attr);
4182 
4183       for (av = attr->first_value; av; av = av->next)
4184 	if (av != common_av)
4185 	  write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
4186 
4187       write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
4188       printf ("    }\n");
4189     }
4190 
4191   else
4192     {
4193       /* Write a nested CASE.  The first indicates which condition we need to
4194 	 test, and the inner CASE tests the condition.  */
4195       printf ("  insn = candidate_insn;\n");
4196       printf ("  switch (slot)\n");
4197       printf ("    {\n");
4198 
4199       for (delay = delays; delay; delay = delay->next)
4200 	for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
4201 	  {
4202 	    printf ("    case %d:\n",
4203 		    (i / 3) + (num_delays == 1 ? 0 : delay->num * max_slots));
4204 	    printf ("      switch (recog_memoized (insn))\n");
4205 	    printf ("\t{\n");
4206 
4207 	    sprintf (str, "*%s_%d_%d", kind, delay->num, i / 3);
4208 	    pstr = str;
4209 	    attr = find_attr (&pstr, 0);
4210 	    gcc_assert (attr);
4211 	    common_av = find_most_used (attr);
4212 
4213 	    for (av = attr->first_value; av; av = av->next)
4214 	      if (av != common_av)
4215 		write_attr_case (attr, av, 1, "return", ";", 8, true_rtx);
4216 
4217 	    write_attr_case (attr, common_av, 0, "return", ";", 8, true_rtx);
4218 	    printf ("      }\n");
4219 	  }
4220 
4221       printf ("    default:\n");
4222       printf ("      gcc_unreachable ();\n");
4223       printf ("    }\n");
4224     }
4225 
4226   printf ("}\n\n");
4227 }
4228 
4229 /* This page contains miscellaneous utility routines.  */
4230 
4231 /* Given a pointer to a (char *), return a malloc'ed string containing the
4232    next comma-separated element.  Advance the pointer to after the string
4233    scanned, or the end-of-string.  Return NULL if at end of string.  */
4234 
4235 static char *
next_comma_elt(const char ** pstr)4236 next_comma_elt (const char **pstr)
4237 {
4238   const char *start;
4239 
4240   start = scan_comma_elt (pstr);
4241 
4242   if (start == NULL)
4243     return NULL;
4244 
4245   return attr_string (start, *pstr - start);
4246 }
4247 
4248 /* Return a `struct attr_desc' pointer for a given named attribute.  If CREATE
4249    is nonzero, build a new attribute, if one does not exist.  *NAME_P is
4250    replaced by a pointer to a canonical copy of the string.  */
4251 
4252 static struct attr_desc *
find_attr(const char ** name_p,int create)4253 find_attr (const char **name_p, int create)
4254 {
4255   struct attr_desc *attr;
4256   int index;
4257   const char *name = *name_p;
4258 
4259   /* Before we resort to using `strcmp', see if the string address matches
4260      anywhere.  In most cases, it should have been canonicalized to do so.  */
4261   if (name == alternative_name)
4262     return NULL;
4263 
4264   index = name[0] & (MAX_ATTRS_INDEX - 1);
4265   for (attr = attrs[index]; attr; attr = attr->next)
4266     if (name == attr->name)
4267       return attr;
4268 
4269   /* Otherwise, do it the slow way.  */
4270   for (attr = attrs[index]; attr; attr = attr->next)
4271     if (name[0] == attr->name[0] && ! strcmp (name, attr->name))
4272       {
4273 	*name_p = attr->name;
4274 	return attr;
4275       }
4276 
4277   if (! create)
4278     return NULL;
4279 
4280   attr = oballoc (sizeof (struct attr_desc));
4281   attr->name = DEF_ATTR_STRING (name);
4282   attr->first_value = attr->default_val = NULL;
4283   attr->is_numeric = attr->is_const = attr->is_special = 0;
4284   attr->static_p = 0;
4285   attr->next = attrs[index];
4286   attrs[index] = attr;
4287 
4288   *name_p = attr->name;
4289 
4290   return attr;
4291 }
4292 
4293 /* Create internal attribute with the given default value.  */
4294 
4295 void
make_internal_attr(const char * name,rtx value,int special)4296 make_internal_attr (const char *name, rtx value, int special)
4297 {
4298   struct attr_desc *attr;
4299 
4300   attr = find_attr (&name, 1);
4301   gcc_assert (!attr->default_val);
4302 
4303   attr->is_numeric = 1;
4304   attr->is_const = 0;
4305   attr->is_special = (special & ATTR_SPECIAL) != 0;
4306   attr->static_p = (special & ATTR_STATIC) != 0;
4307   attr->default_val = get_attr_value (value, attr, -2);
4308 }
4309 
4310 /* Find the most used value of an attribute.  */
4311 
4312 static struct attr_value *
find_most_used(struct attr_desc * attr)4313 find_most_used (struct attr_desc *attr)
4314 {
4315   struct attr_value *av;
4316   struct attr_value *most_used;
4317   int nuses;
4318 
4319   most_used = NULL;
4320   nuses = -1;
4321 
4322   for (av = attr->first_value; av; av = av->next)
4323     if (av->num_insns > nuses)
4324       nuses = av->num_insns, most_used = av;
4325 
4326   return most_used;
4327 }
4328 
4329 /* Return (attr_value "n") */
4330 
4331 rtx
make_numeric_value(int n)4332 make_numeric_value (int n)
4333 {
4334   static rtx int_values[20];
4335   rtx exp;
4336   char *p;
4337 
4338   gcc_assert (n >= 0);
4339 
4340   if (n < 20 && int_values[n])
4341     return int_values[n];
4342 
4343   p = attr_printf (MAX_DIGITS, "%d", n);
4344   exp = attr_rtx (CONST_STRING, p);
4345 
4346   if (n < 20)
4347     int_values[n] = exp;
4348 
4349   return exp;
4350 }
4351 
4352 static rtx
copy_rtx_unchanging(rtx orig)4353 copy_rtx_unchanging (rtx orig)
4354 {
4355   if (ATTR_IND_SIMPLIFIED_P (orig) || ATTR_CURR_SIMPLIFIED_P (orig))
4356     return orig;
4357 
4358   ATTR_CURR_SIMPLIFIED_P (orig) = 1;
4359   return orig;
4360 }
4361 
4362 /* Determine if an insn has a constant number of delay slots, i.e., the
4363    number of delay slots is not a function of the length of the insn.  */
4364 
4365 static void
write_const_num_delay_slots(void)4366 write_const_num_delay_slots (void)
4367 {
4368   struct attr_desc *attr = find_attr (&num_delay_slots_str, 0);
4369   struct attr_value *av;
4370 
4371   if (attr)
4372     {
4373       printf ("int\nconst_num_delay_slots (rtx insn)\n");
4374       printf ("{\n");
4375       printf ("  switch (recog_memoized (insn))\n");
4376       printf ("    {\n");
4377 
4378       for (av = attr->first_value; av; av = av->next)
4379 	{
4380 	  length_used = 0;
4381 	  walk_attr_value (av->value);
4382 	  if (length_used)
4383 	    write_insn_cases (av->first_insn, 4);
4384 	}
4385 
4386       printf ("    default:\n");
4387       printf ("      return 1;\n");
4388       printf ("    }\n}\n\n");
4389     }
4390 }
4391 
4392 int
main(int argc,char ** argv)4393 main (int argc, char **argv)
4394 {
4395   rtx desc;
4396   struct attr_desc *attr;
4397   struct insn_def *id;
4398   rtx tem;
4399   int i;
4400 
4401   progname = "genattrtab";
4402 
4403   if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
4404     return (FATAL_EXIT_CODE);
4405 
4406   obstack_init (hash_obstack);
4407   obstack_init (temp_obstack);
4408 
4409   /* Set up true and false rtx's */
4410   true_rtx = rtx_alloc (CONST_INT);
4411   XWINT (true_rtx, 0) = 1;
4412   false_rtx = rtx_alloc (CONST_INT);
4413   XWINT (false_rtx, 0) = 0;
4414   ATTR_IND_SIMPLIFIED_P (true_rtx) = ATTR_IND_SIMPLIFIED_P (false_rtx) = 1;
4415   ATTR_PERMANENT_P (true_rtx) = ATTR_PERMANENT_P (false_rtx) = 1;
4416 
4417   alternative_name = DEF_ATTR_STRING ("alternative");
4418   length_str = DEF_ATTR_STRING ("length");
4419   delay_type_str = DEF_ATTR_STRING ("*delay_type");
4420   delay_1_0_str = DEF_ATTR_STRING ("*delay_1_0");
4421   num_delay_slots_str = DEF_ATTR_STRING ("*num_delay_slots");
4422 
4423   printf ("/* Generated automatically by the program `genattrtab'\n\
4424 from the machine description file `md'.  */\n\n");
4425 
4426   /* Read the machine description.  */
4427 
4428   initiate_automaton_gen (argc, argv);
4429   while (1)
4430     {
4431       int lineno;
4432 
4433       desc = read_md_rtx (&lineno, &insn_code_number);
4434       if (desc == NULL)
4435 	break;
4436 
4437       switch (GET_CODE (desc))
4438 	{
4439 	case DEFINE_INSN:
4440 	case DEFINE_PEEPHOLE:
4441 	case DEFINE_ASM_ATTRIBUTES:
4442 	  gen_insn (desc, lineno);
4443 	  break;
4444 
4445 	case DEFINE_ATTR:
4446 	  gen_attr (desc, lineno);
4447 	  break;
4448 
4449 	case DEFINE_DELAY:
4450 	  gen_delay (desc, lineno);
4451 	  break;
4452 
4453 	case DEFINE_CPU_UNIT:
4454 	  gen_cpu_unit (desc);
4455 	  break;
4456 
4457 	case DEFINE_QUERY_CPU_UNIT:
4458 	  gen_query_cpu_unit (desc);
4459 	  break;
4460 
4461 	case DEFINE_BYPASS:
4462 	  gen_bypass (desc);
4463 	  break;
4464 
4465 	case EXCLUSION_SET:
4466 	  gen_excl_set (desc);
4467 	  break;
4468 
4469 	case PRESENCE_SET:
4470 	  gen_presence_set (desc);
4471 	  break;
4472 
4473 	case FINAL_PRESENCE_SET:
4474 	  gen_final_presence_set (desc);
4475 	  break;
4476 
4477 	case ABSENCE_SET:
4478 	  gen_absence_set (desc);
4479 	  break;
4480 
4481 	case FINAL_ABSENCE_SET:
4482 	  gen_final_absence_set (desc);
4483 	  break;
4484 
4485 	case DEFINE_AUTOMATON:
4486 	  gen_automaton (desc);
4487 	  break;
4488 
4489 	case AUTOMATA_OPTION:
4490 	  gen_automata_option (desc);
4491 	  break;
4492 
4493 	case DEFINE_RESERVATION:
4494 	  gen_reserv (desc);
4495 	  break;
4496 
4497 	case DEFINE_INSN_RESERVATION:
4498 	  gen_insn_reserv (desc);
4499 	  break;
4500 
4501 	default:
4502 	  break;
4503 	}
4504       if (GET_CODE (desc) != DEFINE_ASM_ATTRIBUTES)
4505 	insn_index_number++;
4506     }
4507 
4508   if (have_error)
4509     return FATAL_EXIT_CODE;
4510 
4511   insn_code_number++;
4512 
4513   /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one.  */
4514   if (! got_define_asm_attributes)
4515     {
4516       tem = rtx_alloc (DEFINE_ASM_ATTRIBUTES);
4517       XVEC (tem, 0) = rtvec_alloc (0);
4518       gen_insn (tem, 0);
4519     }
4520 
4521   /* Expand DEFINE_DELAY information into new attribute.  */
4522   if (num_delays)
4523     expand_delays ();
4524 
4525   /* Build DFA, output some functions and expand DFA information
4526      to new attributes.  */
4527   if (num_dfa_decls)
4528     expand_automata ();
4529 
4530   printf ("#include \"config.h\"\n");
4531   printf ("#include \"system.h\"\n");
4532   printf ("#include \"coretypes.h\"\n");
4533   printf ("#include \"tm.h\"\n");
4534   printf ("#include \"rtl.h\"\n");
4535   printf ("#include \"tm_p.h\"\n");
4536   printf ("#include \"insn-config.h\"\n");
4537   printf ("#include \"recog.h\"\n");
4538   printf ("#include \"regs.h\"\n");
4539   printf ("#include \"real.h\"\n");
4540   printf ("#include \"output.h\"\n");
4541   printf ("#include \"insn-attr.h\"\n");
4542   printf ("#include \"toplev.h\"\n");
4543   printf ("#include \"flags.h\"\n");
4544   printf ("#include \"function.h\"\n");
4545   printf ("\n");
4546   printf ("#define operands recog_data.operand\n\n");
4547 
4548   /* Make `insn_alternatives'.  */
4549   insn_alternatives = oballoc (insn_code_number * sizeof (int));
4550   for (id = defs; id; id = id->next)
4551     if (id->insn_code >= 0)
4552       insn_alternatives[id->insn_code] = (1 << id->num_alternatives) - 1;
4553 
4554   /* Make `insn_n_alternatives'.  */
4555   insn_n_alternatives = oballoc (insn_code_number * sizeof (int));
4556   for (id = defs; id; id = id->next)
4557     if (id->insn_code >= 0)
4558       insn_n_alternatives[id->insn_code] = id->num_alternatives;
4559 
4560   /* Prepare to write out attribute subroutines by checking everything stored
4561      away and building the attribute cases.  */
4562 
4563   check_defs ();
4564 
4565   for (i = 0; i < MAX_ATTRS_INDEX; i++)
4566     for (attr = attrs[i]; attr; attr = attr->next)
4567       attr->default_val->value
4568 	= check_attr_value (attr->default_val->value, attr);
4569 
4570   if (have_error)
4571     return FATAL_EXIT_CODE;
4572 
4573   for (i = 0; i < MAX_ATTRS_INDEX; i++)
4574     for (attr = attrs[i]; attr; attr = attr->next)
4575       fill_attr (attr);
4576 
4577   /* Construct extra attributes for `length'.  */
4578   make_length_attrs ();
4579 
4580   /* Perform any possible optimizations to speed up compilation.  */
4581   optimize_attrs ();
4582 
4583   /* Now write out all the `gen_attr_...' routines.  Do these before the
4584      special routines so that they get defined before they are used.  */
4585 
4586   for (i = 0; i < MAX_ATTRS_INDEX; i++)
4587     for (attr = attrs[i]; attr; attr = attr->next)
4588       {
4589 	if (! attr->is_special && ! attr->is_const)
4590 	  {
4591 	    int insn_alts_p;
4592 
4593 	    insn_alts_p
4594 	      = (attr->name [0] == '*'
4595 		 && strcmp (&attr->name[1], INSN_ALTS_FUNC_NAME) == 0);
4596 	    if (insn_alts_p)
4597 	      printf ("\n#if AUTOMATON_ALTS\n");
4598 	    write_attr_get (attr);
4599 	    if (insn_alts_p)
4600 	      printf ("#endif\n\n");
4601 	  }
4602       }
4603 
4604   /* Write out delay eligibility information, if DEFINE_DELAY present.
4605      (The function to compute the number of delay slots will be written
4606      below.)  */
4607   if (num_delays)
4608     {
4609       write_eligible_delay ("delay");
4610       if (have_annul_true)
4611 	write_eligible_delay ("annul_true");
4612       if (have_annul_false)
4613 	write_eligible_delay ("annul_false");
4614     }
4615 
4616   /* Output code for pipeline hazards recognition based on DFA
4617      (deterministic finite-state automata).  */
4618   if (num_dfa_decls)
4619     write_automata ();
4620 
4621   /* Write out constant delay slot info.  */
4622   write_const_num_delay_slots ();
4623 
4624   write_length_unit_log ();
4625 
4626   fflush (stdout);
4627   return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
4628 }
4629 
4630 /* Define this so we can link with print-rtl.o to get debug_rtx function.  */
4631 const char *
get_insn_name(int code ATTRIBUTE_UNUSED)4632 get_insn_name (int code ATTRIBUTE_UNUSED)
4633 {
4634   return NULL;
4635 }
4636