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