1 /* Generate code from machine description to compute values of attributes.
2    Copyright (C) 1991-2020 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.c was written out containing many large
304    functions and tables.  This made insn-attrtab.c _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 CC0:
3015     case EQ_ATTR:
3016     case ATTR_FLAG:
3017       return;
3018 
3019     default:
3020       break;
3021     }
3022 
3023   /* Compare the elements.  If any pair of corresponding elements
3024      fail to match, return 0 for the whole things.  */
3025 
3026   fmt = GET_RTX_FORMAT (code);
3027   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
3028     {
3029       switch (fmt[i])
3030 	{
3031 	case 'V':
3032 	case 'E':
3033 	  for (j = 0; j < XVECLEN (x, i); j++)
3034 	    clear_struct_flag (XVECEXP (x, i, j));
3035 	  break;
3036 
3037 	case 'e':
3038 	  clear_struct_flag (XEXP (x, i));
3039 	  break;
3040 	}
3041     }
3042 }
3043 
3044 /* Add attribute value NAME to the beginning of ATTR's list.  */
3045 
3046 static void
add_attr_value(class attr_desc * attr,const char * name)3047 add_attr_value (class attr_desc *attr, const char *name)
3048 {
3049   struct attr_value *av;
3050 
3051   av = oballoc (struct attr_value);
3052   av->value = attr_rtx (CONST_STRING, name);
3053   av->next = attr->first_value;
3054   attr->first_value = av;
3055   av->first_insn = NULL;
3056   av->num_insns = 0;
3057   av->has_asm_insn = 0;
3058 }
3059 
3060 /* Create table entries for DEFINE_ATTR or DEFINE_ENUM_ATTR.  */
3061 
3062 static void
gen_attr(md_rtx_info * info)3063 gen_attr (md_rtx_info *info)
3064 {
3065   struct enum_type *et;
3066   struct enum_value *ev;
3067   class attr_desc *attr;
3068   const char *name_ptr;
3069   char *p;
3070   rtx def = info->def;
3071 
3072   /* Make a new attribute structure.  Check for duplicate by looking at
3073      attr->default_val, since it is initialized by this routine.  */
3074   attr = find_attr (&XSTR (def, 0), 1);
3075   if (attr->default_val)
3076     {
3077       error_at (info->loc, "duplicate definition for attribute %s",
3078 		attr->name);
3079       message_at (attr->loc, "previous definition");
3080       return;
3081     }
3082   attr->loc = info->loc;
3083 
3084   if (GET_CODE (def) == DEFINE_ENUM_ATTR)
3085     {
3086       attr->enum_name = XSTR (def, 1);
3087       et = rtx_reader_ptr->lookup_enum_type (XSTR (def, 1));
3088       if (!et || !et->md_p)
3089 	error_at (info->loc, "No define_enum called `%s' defined",
3090 		  attr->name);
3091       if (et)
3092 	for (ev = et->values; ev; ev = ev->next)
3093 	  add_attr_value (attr, ev->name);
3094     }
3095   else if (*XSTR (def, 1) == '\0')
3096     attr->is_numeric = 1;
3097   else
3098     {
3099       name_ptr = XSTR (def, 1);
3100       while ((p = next_comma_elt (&name_ptr)) != NULL)
3101 	add_attr_value (attr, p);
3102     }
3103 
3104   if (GET_CODE (XEXP (def, 2)) == CONST)
3105     {
3106       attr->is_const = 1;
3107       if (attr->is_numeric)
3108 	error_at (info->loc,
3109 		  "constant attributes may not take numeric values");
3110 
3111       /* Get rid of the CONST node.  It is allowed only at top-level.  */
3112       XEXP (def, 2) = XEXP (XEXP (def, 2), 0);
3113     }
3114 
3115   if (! strcmp_check (attr->name, length_str) && ! attr->is_numeric)
3116     error_at (info->loc, "`length' attribute must take numeric values");
3117 
3118   /* Set up the default value.  */
3119   XEXP (def, 2) = check_attr_value (info->loc, XEXP (def, 2), attr);
3120   attr->default_val = get_attr_value (info->loc, XEXP (def, 2), attr, -2);
3121 }
3122 
3123 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
3124    alternatives in the constraints.  Assume all MATCH_OPERANDs have the same
3125    number of alternatives as this should be checked elsewhere.  */
3126 
3127 static int
count_alternatives(rtx exp)3128 count_alternatives (rtx exp)
3129 {
3130   int i, j, n;
3131   const char *fmt;
3132 
3133   if (GET_CODE (exp) == MATCH_OPERAND)
3134     return n_comma_elts (XSTR (exp, 2));
3135 
3136   for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
3137        i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
3138     switch (*fmt++)
3139       {
3140       case 'e':
3141       case 'u':
3142 	n = count_alternatives (XEXP (exp, i));
3143 	if (n)
3144 	  return n;
3145 	break;
3146 
3147       case 'E':
3148       case 'V':
3149 	if (XVEC (exp, i) != NULL)
3150 	  for (j = 0; j < XVECLEN (exp, i); j++)
3151 	    {
3152 	      n = count_alternatives (XVECEXP (exp, i, j));
3153 	      if (n)
3154 		return n;
3155 	    }
3156       }
3157 
3158   return 0;
3159 }
3160 
3161 /* Returns nonzero if the given expression contains an EQ_ATTR with the
3162    `alternative' attribute.  */
3163 
3164 static int
compares_alternatives_p(rtx exp)3165 compares_alternatives_p (rtx exp)
3166 {
3167   int i, j;
3168   const char *fmt;
3169 
3170   if (GET_CODE (exp) == EQ_ATTR && XSTR (exp, 0) == alternative_name)
3171     return 1;
3172 
3173   for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
3174        i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
3175     switch (*fmt++)
3176       {
3177       case 'e':
3178       case 'u':
3179 	if (compares_alternatives_p (XEXP (exp, i)))
3180 	  return 1;
3181 	break;
3182 
3183       case 'E':
3184 	for (j = 0; j < XVECLEN (exp, i); j++)
3185 	  if (compares_alternatives_p (XVECEXP (exp, i, j)))
3186 	    return 1;
3187 	break;
3188       }
3189 
3190   return 0;
3191 }
3192 
3193 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES.  */
3194 
3195 static void
gen_insn(md_rtx_info * info)3196 gen_insn (md_rtx_info *info)
3197 {
3198   class insn_def *id;
3199   rtx def = info->def;
3200 
3201   id = oballoc (class insn_def);
3202   id->next = defs;
3203   defs = id;
3204   id->def = def;
3205   id->loc = info->loc;
3206 
3207   switch (GET_CODE (def))
3208     {
3209     case DEFINE_INSN:
3210       id->insn_code = info->index;
3211       id->insn_index = insn_index_number;
3212       id->num_alternatives = count_alternatives (def);
3213       if (id->num_alternatives == 0)
3214 	id->num_alternatives = 1;
3215       id->vec_idx = 4;
3216       break;
3217 
3218     case DEFINE_PEEPHOLE:
3219       id->insn_code = info->index;
3220       id->insn_index = insn_index_number;
3221       id->num_alternatives = count_alternatives (def);
3222       if (id->num_alternatives == 0)
3223 	id->num_alternatives = 1;
3224       id->vec_idx = 3;
3225       break;
3226 
3227     case DEFINE_ASM_ATTRIBUTES:
3228       id->insn_code = -1;
3229       id->insn_index = -1;
3230       id->num_alternatives = 1;
3231       id->vec_idx = 0;
3232       got_define_asm_attributes = 1;
3233       break;
3234 
3235     default:
3236       gcc_unreachable ();
3237     }
3238 }
3239 
3240 /* Process a DEFINE_DELAY.  Validate the vector length, check if annul
3241    true or annul false is specified, and make a `struct delay_desc'.  */
3242 
3243 static void
gen_delay(md_rtx_info * info)3244 gen_delay (md_rtx_info *info)
3245 {
3246   class delay_desc *delay;
3247   int i;
3248 
3249   rtx def = info->def;
3250   if (XVECLEN (def, 1) % 3 != 0)
3251     {
3252       error_at (info->loc, "number of elements in DEFINE_DELAY must"
3253 		" be multiple of three");
3254       return;
3255     }
3256 
3257   for (i = 0; i < XVECLEN (def, 1); i += 3)
3258     {
3259       if (XVECEXP (def, 1, i + 1))
3260 	have_annul_true = 1;
3261       if (XVECEXP (def, 1, i + 2))
3262 	have_annul_false = 1;
3263     }
3264 
3265   delay = oballoc (class delay_desc);
3266   delay->def = def;
3267   delay->num = ++num_delays;
3268   delay->next = delays;
3269   delay->loc = info->loc;
3270   delays = delay;
3271 }
3272 
3273 /* Names of attributes that could be possibly cached.  */
3274 static const char *cached_attrs[32];
3275 /* Number of such attributes.  */
3276 static int cached_attr_count;
3277 /* Bitmasks of possibly cached attributes.  */
3278 static unsigned int attrs_seen_once, attrs_seen_more_than_once;
3279 static unsigned int attrs_to_cache;
3280 static unsigned int attrs_cached_inside, attrs_cached_after;
3281 
3282 /* Finds non-const attributes that could be possibly cached.
3283    When create is TRUE, fills in cached_attrs array.
3284    Computes ATTRS_SEEN_ONCE and ATTRS_SEEN_MORE_THAN_ONCE
3285    bitmasks.  */
3286 
3287 static void
find_attrs_to_cache(rtx exp,bool create)3288 find_attrs_to_cache (rtx exp, bool create)
3289 {
3290   int i;
3291   const char *name;
3292   class attr_desc *attr;
3293 
3294   if (exp == NULL)
3295     return;
3296 
3297   switch (GET_CODE (exp))
3298     {
3299     case NOT:
3300       if (GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
3301 	find_attrs_to_cache (XEXP (exp, 0), create);
3302       return;
3303 
3304     case EQ_ATTR:
3305       name = XSTR (exp, 0);
3306       if (name == alternative_name)
3307 	return;
3308       for (i = 0; i < cached_attr_count; i++)
3309 	if (name == cached_attrs[i])
3310 	  {
3311 	    if ((attrs_seen_once & (1U << i)) != 0)
3312 	      attrs_seen_more_than_once |= (1U << i);
3313 	    else
3314 	      attrs_seen_once |= (1U << i);
3315 	    return;
3316 	  }
3317       if (!create)
3318 	return;
3319       attr = find_attr (&name, 0);
3320       gcc_assert (attr);
3321       if (attr->is_const)
3322 	return;
3323       if (cached_attr_count == 32)
3324 	return;
3325       cached_attrs[cached_attr_count] = XSTR (exp, 0);
3326       attrs_seen_once |= (1U << cached_attr_count);
3327       cached_attr_count++;
3328       return;
3329 
3330     case AND:
3331     case IOR:
3332       find_attrs_to_cache (XEXP (exp, 0), create);
3333       find_attrs_to_cache (XEXP (exp, 1), create);
3334       return;
3335 
3336     case COND:
3337       for (i = 0; i < XVECLEN (exp, 0); i += 2)
3338 	find_attrs_to_cache (XVECEXP (exp, 0, i), create);
3339       return;
3340 
3341     default:
3342       return;
3343     }
3344 }
3345 
3346 /* Given a piece of RTX, print a C expression to test its truth value to OUTF.
3347    We use AND and IOR both for logical and bit-wise operations, so
3348    interpret them as logical unless they are inside a comparison expression.
3349 
3350    An outermost pair of parentheses is emitted around this C expression unless
3351    EMIT_PARENS is false.  */
3352 
3353 /* Interpret AND/IOR as bit-wise operations instead of logical.  */
3354 #define FLG_BITWISE		1
3355 /* Set if cached attribute will be known initialized in else block after
3356    this condition.  This is true for LHS of toplevel && and || and
3357    even for RHS of ||, but not for RHS of &&.  */
3358 #define FLG_AFTER		2
3359 /* Set if cached attribute will be known initialized in then block after
3360    this condition.  This is true for LHS of toplevel && and || and
3361    even for RHS of &&, but not for RHS of ||.  */
3362 #define FLG_INSIDE		4
3363 /* Cleared when an operand of &&.  */
3364 #define FLG_OUTSIDE_AND		8
3365 
3366 static unsigned int
3367 write_test_expr (FILE *outf, rtx exp, unsigned int attrs_cached, int flags,
3368 		 bool emit_parens = true)
3369 {
3370   int comparison_operator = 0;
3371   RTX_CODE code;
3372   class attr_desc *attr;
3373 
3374   if (emit_parens)
3375     fprintf (outf, "(");
3376 
3377   code = GET_CODE (exp);
3378   switch (code)
3379     {
3380     /* Binary operators.  */
3381     case GEU: case GTU:
3382     case LEU: case LTU:
3383       fprintf (outf, "(unsigned) ");
3384       /* Fall through.  */
3385 
3386     case EQ: case NE:
3387     case GE: case GT:
3388     case LE: case LT:
3389       comparison_operator = FLG_BITWISE;
3390       /* FALLTHRU */
3391 
3392     case PLUS:   case MINUS:  case MULT:     case DIV:      case MOD:
3393     case AND:    case IOR:    case XOR:
3394     case ASHIFT: case LSHIFTRT: case ASHIFTRT:
3395       if ((code != AND && code != IOR) || (flags & FLG_BITWISE))
3396 	{
3397 	  flags &= ~(FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND);
3398 	  write_test_expr (outf, XEXP (exp, 0), attrs_cached,
3399 			   flags | comparison_operator);
3400 	}
3401       else
3402 	{
3403 	  if (code == AND)
3404 	    flags &= ~FLG_OUTSIDE_AND;
3405 	  if (GET_CODE (XEXP (exp, 0)) == code
3406 	      || GET_CODE (XEXP (exp, 0)) == EQ_ATTR
3407 	      || (GET_CODE (XEXP (exp, 0)) == NOT
3408 		  && GET_CODE (XEXP (XEXP (exp, 0), 0)) == EQ_ATTR))
3409 	    attrs_cached
3410 	      = write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags);
3411 	  else
3412 	    write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags);
3413 	}
3414       switch (code)
3415 	{
3416 	case EQ:
3417 	  fprintf (outf, " == ");
3418 	  break;
3419 	case NE:
3420 	  fprintf (outf, " != ");
3421 	  break;
3422 	case GE:
3423 	  fprintf (outf, " >= ");
3424 	  break;
3425 	case GT:
3426 	  fprintf (outf, " > ");
3427 	  break;
3428 	case GEU:
3429 	  fprintf (outf, " >= (unsigned) ");
3430 	  break;
3431 	case GTU:
3432 	  fprintf (outf, " > (unsigned) ");
3433 	  break;
3434 	case LE:
3435 	  fprintf (outf, " <= ");
3436 	  break;
3437 	case LT:
3438 	  fprintf (outf, " < ");
3439 	  break;
3440 	case LEU:
3441 	  fprintf (outf, " <= (unsigned) ");
3442 	  break;
3443 	case LTU:
3444 	  fprintf (outf, " < (unsigned) ");
3445 	  break;
3446 	case PLUS:
3447 	  fprintf (outf, " + ");
3448 	  break;
3449 	case MINUS:
3450 	  fprintf (outf, " - ");
3451 	  break;
3452 	case MULT:
3453 	  fprintf (outf, " * ");
3454 	  break;
3455 	case DIV:
3456 	  fprintf (outf, " / ");
3457 	  break;
3458 	case MOD:
3459 	  fprintf (outf, " %% ");
3460 	  break;
3461 	case AND:
3462 	  if (flags & FLG_BITWISE)
3463 	    fprintf (outf, " & ");
3464 	  else
3465 	    fprintf (outf, " && ");
3466 	  break;
3467 	case IOR:
3468 	  if (flags & FLG_BITWISE)
3469 	    fprintf (outf, " | ");
3470 	  else
3471 	    fprintf (outf, " || ");
3472 	  break;
3473 	case XOR:
3474 	  fprintf (outf, " ^ ");
3475 	  break;
3476 	case ASHIFT:
3477 	  fprintf (outf, " << ");
3478 	  break;
3479 	case LSHIFTRT:
3480 	case ASHIFTRT:
3481 	  fprintf (outf, " >> ");
3482 	  break;
3483 	default:
3484 	  gcc_unreachable ();
3485 	}
3486 
3487       if (code == AND)
3488 	{
3489 	  /* For if (something && (cached_x = get_attr_x (insn)) == X)
3490 	     cached_x is only known to be initialized in then block.  */
3491 	  flags &= ~FLG_AFTER;
3492 	}
3493       else if (code == IOR)
3494 	{
3495 	  if (flags & FLG_OUTSIDE_AND)
3496 	    /* For if (something || (cached_x = get_attr_x (insn)) == X)
3497 	       cached_x is only known to be initialized in else block
3498 	       and else if conditions.  */
3499 	    flags &= ~FLG_INSIDE;
3500 	  else
3501 	    /* For if ((something || (cached_x = get_attr_x (insn)) == X)
3502 		       && something_else)
3503 	       cached_x is not know to be initialized anywhere.  */
3504 	    flags &= ~(FLG_AFTER | FLG_INSIDE);
3505 	}
3506       if ((code == AND || code == IOR)
3507 	  && (GET_CODE (XEXP (exp, 1)) == code
3508 	      || GET_CODE (XEXP (exp, 1)) == EQ_ATTR
3509 	      || (GET_CODE (XEXP (exp, 1)) == NOT
3510 		  && GET_CODE (XEXP (XEXP (exp, 1), 0)) == EQ_ATTR)))
3511 	{
3512 	  bool need_parens = true;
3513 
3514 	  /* No need to emit parentheses around the right-hand operand if we are
3515 	     continuing a chain of && or || (or & or |).  */
3516 	  if (GET_CODE (XEXP (exp, 1)) == code)
3517 	    need_parens = false;
3518 
3519 	  attrs_cached
3520 	    = write_test_expr (outf, XEXP (exp, 1), attrs_cached, flags,
3521 			       need_parens);
3522 	}
3523       else
3524 	write_test_expr (outf, XEXP (exp, 1), attrs_cached,
3525 			 flags | comparison_operator);
3526       break;
3527 
3528     case NOT:
3529       /* Special-case (not (eq_attrq "alternative" "x")) */
3530       if (! (flags & FLG_BITWISE) && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
3531 	{
3532 	  if (XSTR (XEXP (exp, 0), 0) == alternative_name)
3533 	    {
3534 	      fprintf (outf, "which_alternative != %s",
3535 		       XSTR (XEXP (exp, 0), 1));
3536 	      break;
3537 	    }
3538 
3539 	  fprintf (outf, "! ");
3540 	  attrs_cached =
3541 	    write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags);
3542 	  break;
3543 	}
3544 
3545       /* Otherwise, fall through to normal unary operator.  */
3546       gcc_fallthrough ();
3547 
3548     /* Unary operators.  */
3549     case ABS:  case NEG:
3550       switch (code)
3551 	{
3552 	case NOT:
3553 	  if (flags & FLG_BITWISE)
3554 	    fprintf (outf, "~ ");
3555 	  else
3556 	    fprintf (outf, "! ");
3557 	  break;
3558 	case ABS:
3559 	  fprintf (outf, "abs ");
3560 	  break;
3561 	case NEG:
3562 	  fprintf (outf, "-");
3563 	  break;
3564 	default:
3565 	  gcc_unreachable ();
3566 	}
3567 
3568       flags &= ~(FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND);
3569       write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags);
3570       break;
3571 
3572     case EQ_ATTR_ALT:
3573 	{
3574 	  alternative_mask set = XWINT (exp, 0);
3575 	  int bit = 0;
3576 
3577 	  if (flags & FLG_BITWISE)
3578 	    fatal ("EQ_ATTR_ALT not valid inside comparison");
3579 
3580 	  if (!set)
3581 	    fatal ("Empty EQ_ATTR_ALT should be optimized out");
3582 
3583 	  if (!(set & (set - 1)))
3584 	    {
3585 	      if (!(set & 0xffffffff))
3586 		{
3587 		  bit += 32;
3588 		  set >>= 32;
3589 		}
3590 	      if (!(set & 0xffff))
3591 		{
3592 		  bit += 16;
3593 		  set >>= 16;
3594 		}
3595 	      if (!(set & 0xff))
3596 		{
3597 		  bit += 8;
3598 		  set >>= 8;
3599 		}
3600 	      if (!(set & 0xf))
3601 		{
3602 		  bit += 4;
3603 		  set >>= 4;
3604 		}
3605 	      if (!(set & 0x3))
3606 		{
3607 		  bit += 2;
3608 		  set >>= 2;
3609 		}
3610 	      if (!(set & 1))
3611 		bit++;
3612 
3613 	      fprintf (outf, "which_alternative %s= %d",
3614 		       XWINT (exp, 1) ? "!" : "=", bit);
3615 	    }
3616 	  else
3617 	    {
3618 	      fprintf (outf, "%s((1ULL << which_alternative) & %#" PRIx64
3619 			     "ULL)",
3620 		       XWINT (exp, 1) ? "!" : "", set);
3621 	    }
3622 	}
3623       break;
3624 
3625     /* Comparison test of an attribute with a value.  Most of these will
3626        have been removed by optimization.   Handle "alternative"
3627        specially and give error if EQ_ATTR present inside a comparison.  */
3628     case EQ_ATTR:
3629       if (flags & FLG_BITWISE)
3630 	fatal ("EQ_ATTR not valid inside comparison");
3631 
3632       if (XSTR (exp, 0) == alternative_name)
3633 	{
3634 	  fprintf (outf, "which_alternative == %s", XSTR (exp, 1));
3635 	  break;
3636 	}
3637 
3638       attr = find_attr (&XSTR (exp, 0), 0);
3639       gcc_assert (attr);
3640 
3641       /* Now is the time to expand the value of a constant attribute.  */
3642       if (attr->is_const)
3643 	{
3644 	  write_test_expr (outf,
3645 			   evaluate_eq_attr (exp, attr,
3646 					     attr->default_val->value,
3647 					     -2, -2),
3648 			   attrs_cached, 0);
3649 	}
3650       else
3651 	{
3652 	  int i;
3653 	  for (i = 0; i < cached_attr_count; i++)
3654 	    if (attr->name == cached_attrs[i])
3655 	      break;
3656 	  if (i < cached_attr_count && (attrs_cached & (1U << i)) != 0)
3657 	    fprintf (outf, "cached_%s", attr->name);
3658 	  else if (i < cached_attr_count && (attrs_to_cache & (1U << i)) != 0)
3659 	    {
3660 	      fprintf (outf, "(cached_%s = get_attr_%s (insn))",
3661 		      attr->name, attr->name);
3662 	      if (flags & FLG_AFTER)
3663 		attrs_cached_after |= (1U << i);
3664 	      if (flags & FLG_INSIDE)
3665 		attrs_cached_inside |= (1U << i);
3666 	      attrs_cached |= (1U << i);
3667 	    }
3668 	  else
3669 	    fprintf (outf, "get_attr_%s (insn)", attr->name);
3670 	  fprintf (outf, " == ");
3671 	  write_attr_valueq (outf, attr, XSTR (exp, 1));
3672 	}
3673       break;
3674 
3675     /* Comparison test of flags for define_delays.  */
3676     case ATTR_FLAG:
3677       if (flags & FLG_BITWISE)
3678 	fatal ("ATTR_FLAG not valid inside comparison");
3679       fprintf (outf, "(flags & ATTR_FLAG_%s) != 0", XSTR (exp, 0));
3680       break;
3681 
3682     /* See if an operand matches a predicate.  */
3683     case MATCH_OPERAND:
3684       /* If only a mode is given, just ensure the mode matches the operand.
3685 	 If neither a mode nor predicate is given, error.  */
3686       if (XSTR (exp, 1) == NULL || *XSTR (exp, 1) == '\0')
3687 	{
3688 	  if (GET_MODE (exp) == VOIDmode)
3689 	    fatal ("null MATCH_OPERAND specified as test");
3690 	  else
3691 	    fprintf (outf, "GET_MODE (operands[%d]) == %smode",
3692 		     XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
3693 	}
3694       else
3695 	fprintf (outf, "%s (operands[%d], %smode)",
3696 		 XSTR (exp, 1), XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
3697       break;
3698 
3699     /* Constant integer.  */
3700     case CONST_INT:
3701       fprintf (outf, HOST_WIDE_INT_PRINT_DEC, XWINT (exp, 0));
3702       break;
3703 
3704     case MATCH_TEST:
3705       rtx_reader_ptr->fprint_c_condition (outf, XSTR (exp, 0));
3706       if (flags & FLG_BITWISE)
3707 	fprintf (outf, " != 0");
3708       break;
3709 
3710     /* A random C expression.  */
3711     case SYMBOL_REF:
3712       rtx_reader_ptr->fprint_c_condition (outf, XSTR (exp, 0));
3713       break;
3714 
3715     /* The address of the branch target.  */
3716     case MATCH_DUP:
3717       fprintf (outf,
3718 	       "INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
3719 	       XINT (exp, 0), XINT (exp, 0), XINT (exp, 0));
3720       break;
3721 
3722     case PC:
3723       /* The address of the current insn.  We implement this actually as the
3724 	 address of the current insn for backward branches, but the last
3725 	 address of the next insn for forward branches, and both with
3726 	 adjustments that account for the worst-case possible stretching of
3727 	 intervening alignments between this insn and its destination.  */
3728       fprintf (outf, "insn_current_reference_address (insn)");
3729       break;
3730 
3731     case CONST_STRING:
3732       fprintf (outf, "%s", XSTR (exp, 0));
3733       break;
3734 
3735     case IF_THEN_ELSE:
3736       write_test_expr (outf, XEXP (exp, 0), attrs_cached, 0);
3737       fprintf (outf, " ? ");
3738       write_test_expr (outf, XEXP (exp, 1), attrs_cached, FLG_BITWISE);
3739       fprintf (outf, " : ");
3740       write_test_expr (outf, XEXP (exp, 2), attrs_cached, FLG_BITWISE);
3741       break;
3742 
3743     default:
3744       fatal ("bad RTX code `%s' in attribute calculation\n",
3745 	     GET_RTX_NAME (code));
3746     }
3747 
3748   if (emit_parens)
3749     fprintf (outf, ")");
3750 
3751   return attrs_cached;
3752 }
3753 
3754 /* Given an attribute value expression, return the maximum value that
3755    might be evaluated.  Return INT_MAX if the value can't be
3756    calculated by this function.  */
3757 
3758 static int
max_attr_value(rtx exp)3759 max_attr_value (rtx exp)
3760 {
3761   int current_max;
3762   int i, n;
3763 
3764   switch (GET_CODE (exp))
3765     {
3766     case CONST_STRING:
3767       current_max = atoi (XSTR (exp, 0));
3768       break;
3769 
3770     case CONST_INT:
3771       current_max = INTVAL (exp);
3772       break;
3773 
3774     case PLUS:
3775       current_max = max_attr_value (XEXP (exp, 0));
3776       if (current_max != INT_MAX)
3777 	{
3778 	  n = current_max;
3779 	  current_max = max_attr_value (XEXP (exp, 1));
3780 	  if (current_max != INT_MAX)
3781 	    current_max += n;
3782 	}
3783       break;
3784 
3785     case MINUS:
3786       current_max = max_attr_value (XEXP (exp, 0));
3787       if (current_max != INT_MAX)
3788 	{
3789 	  n = current_max;
3790 	  current_max = min_attr_value (XEXP (exp, 1));
3791 	  if (current_max != INT_MAX)
3792 	    current_max = n - current_max;
3793 	}
3794       break;
3795 
3796     case MULT:
3797       current_max = max_attr_value (XEXP (exp, 0));
3798       if (current_max != INT_MAX)
3799 	{
3800 	  n = current_max;
3801 	  current_max = max_attr_value (XEXP (exp, 1));
3802 	  if (current_max != INT_MAX)
3803 	    current_max *= n;
3804 	}
3805       break;
3806 
3807     case COND:
3808       current_max = max_attr_value (XEXP (exp, 1));
3809       for (i = 0; i < XVECLEN (exp, 0); i += 2)
3810 	{
3811 	  n = max_attr_value (XVECEXP (exp, 0, i + 1));
3812 	  if (n > current_max)
3813 	    current_max = n;
3814 	}
3815       break;
3816 
3817     case IF_THEN_ELSE:
3818       current_max = max_attr_value (XEXP (exp, 1));
3819       n = max_attr_value (XEXP (exp, 2));
3820       if (n > current_max)
3821 	current_max = n;
3822       break;
3823 
3824     default:
3825       current_max = INT_MAX;
3826       break;
3827     }
3828 
3829   return current_max;
3830 }
3831 
3832 /* Given an attribute value expression, return the minimum value that
3833    might be evaluated.  Return INT_MAX if the value can't be
3834    calculated by this function.  Note that when this function can
3835    calculate one value inside IF_THEN_ELSE or some but not all values
3836    inside COND, then it returns the minimum among those values it can
3837    calculate.  */
3838 
3839 static int
min_attr_value(rtx exp)3840 min_attr_value (rtx exp)
3841 {
3842   int current_min;
3843   int i, n;
3844 
3845   switch (GET_CODE (exp))
3846     {
3847     case CONST_STRING:
3848       current_min = atoi (XSTR (exp, 0));
3849       break;
3850 
3851     case CONST_INT:
3852       current_min = INTVAL (exp);
3853       break;
3854 
3855     case PLUS:
3856       current_min = min_attr_value (XEXP (exp, 0));
3857       if (current_min != INT_MAX)
3858 	{
3859 	  n = current_min;
3860 	  current_min = min_attr_value (XEXP (exp, 1));
3861 	  if (current_min != INT_MAX)
3862 	    current_min += n;
3863 	}
3864       break;
3865 
3866     case MINUS:
3867       current_min = min_attr_value (XEXP (exp, 0));
3868       if (current_min != INT_MAX)
3869 	{
3870 	  n = current_min;
3871 	  current_min = max_attr_value (XEXP (exp, 1));
3872 	  if (current_min != INT_MAX)
3873 	    current_min = n - current_min;
3874 	}
3875       break;
3876 
3877     case MULT:
3878       current_min = min_attr_value (XEXP (exp, 0));
3879       if (current_min != INT_MAX)
3880 	{
3881 	  n = current_min;
3882 	  current_min = min_attr_value (XEXP (exp, 1));
3883 	  if (current_min != INT_MAX)
3884 	    current_min *= n;
3885 	}
3886       break;
3887 
3888     case COND:
3889       current_min = min_attr_value (XEXP (exp, 1));
3890       for (i = 0; i < XVECLEN (exp, 0); i += 2)
3891 	{
3892 	  n = min_attr_value (XVECEXP (exp, 0, i + 1));
3893 	  if (n < current_min)
3894 	    current_min = n;
3895 	}
3896       break;
3897 
3898     case IF_THEN_ELSE:
3899       current_min = min_attr_value (XEXP (exp, 1));
3900       n = min_attr_value (XEXP (exp, 2));
3901       if (n < current_min)
3902 	current_min = n;
3903       break;
3904 
3905     default:
3906       current_min = INT_MAX;
3907       break;
3908     }
3909 
3910   return current_min;
3911 }
3912 
3913 /* Given an attribute value expression, return the alignment of values.
3914    Return 0 if EXP is known to be zero, and 1 if the value can't be
3915    calculated by this function.  */
3916 
3917 static unsigned int
attr_value_alignment(rtx exp)3918 attr_value_alignment (rtx exp)
3919 {
3920   unsigned int current_or;
3921   int i;
3922 
3923   switch (GET_CODE (exp))
3924     {
3925     case CONST_STRING:
3926       current_or = atoi (XSTR (exp, 0));
3927       break;
3928 
3929     case CONST_INT:
3930       current_or = INTVAL (exp);
3931       break;
3932 
3933     case PLUS:
3934     case MINUS:
3935       current_or = attr_value_alignment (XEXP (exp, 0));
3936       current_or |= attr_value_alignment (XEXP (exp, 1));
3937       break;
3938 
3939     case MULT:
3940       current_or = attr_value_alignment (XEXP (exp, 0));
3941       current_or *= attr_value_alignment (XEXP (exp, 1));
3942       break;
3943 
3944     case COND:
3945       current_or = attr_value_alignment (XEXP (exp, 1));
3946       for (i = 0; i < XVECLEN (exp, 0); i += 2)
3947 	current_or |= attr_value_alignment (XVECEXP (exp, 0, i + 1));
3948       break;
3949 
3950     case IF_THEN_ELSE:
3951       current_or = attr_value_alignment (XEXP (exp, 1));
3952       current_or |= attr_value_alignment (XEXP (exp, 2));
3953       break;
3954 
3955     default:
3956       current_or = 1;
3957       break;
3958     }
3959 
3960   return current_or & -current_or;
3961 }
3962 
3963 /* Scan an attribute value, possibly a conditional, and record what actions
3964    will be required to do any conditional tests in it.
3965 
3966    Specifically, set
3967 	`must_extract'	  if we need to extract the insn operands
3968 	`must_constrain'  if we must compute `which_alternative'
3969 	`address_used'	  if an address expression was used
3970 	`length_used'	  if an (eq_attr "length" ...) was used
3971  */
3972 
3973 static void
walk_attr_value(rtx exp)3974 walk_attr_value (rtx exp)
3975 {
3976   int i, j;
3977   const char *fmt;
3978   RTX_CODE code;
3979 
3980   if (exp == NULL)
3981     return;
3982 
3983   code = GET_CODE (exp);
3984   switch (code)
3985     {
3986     case SYMBOL_REF:
3987       if (! ATTR_IND_SIMPLIFIED_P (exp))
3988 	/* Since this is an arbitrary expression, it can look at anything.
3989 	   However, constant expressions do not depend on any particular
3990 	   insn.  */
3991 	must_extract = must_constrain = 1;
3992       return;
3993 
3994     case MATCH_OPERAND:
3995       must_extract = 1;
3996       return;
3997 
3998     case MATCH_TEST:
3999     case EQ_ATTR_ALT:
4000       must_extract = must_constrain = 1;
4001       break;
4002 
4003     case EQ_ATTR:
4004       if (XSTR (exp, 0) == alternative_name)
4005 	must_extract = must_constrain = 1;
4006       else if (strcmp_check (XSTR (exp, 0), length_str) == 0)
4007 	length_used = 1;
4008       return;
4009 
4010     case MATCH_DUP:
4011       must_extract = 1;
4012       address_used = 1;
4013       return;
4014 
4015     case PC:
4016       address_used = 1;
4017       return;
4018 
4019     case ATTR_FLAG:
4020       return;
4021 
4022     default:
4023       break;
4024     }
4025 
4026   for (i = 0, fmt = GET_RTX_FORMAT (code); i < GET_RTX_LENGTH (code); i++)
4027     switch (*fmt++)
4028       {
4029       case 'e':
4030       case 'u':
4031 	walk_attr_value (XEXP (exp, i));
4032 	break;
4033 
4034       case 'E':
4035 	if (XVEC (exp, i) != NULL)
4036 	  for (j = 0; j < XVECLEN (exp, i); j++)
4037 	    walk_attr_value (XVECEXP (exp, i, j));
4038 	break;
4039       }
4040 }
4041 
4042 /* Write out a function to obtain the attribute for a given INSN.  */
4043 
4044 static void
write_attr_get(FILE * outf,class attr_desc * attr)4045 write_attr_get (FILE *outf, class attr_desc *attr)
4046 {
4047   struct attr_value *av, *common_av;
4048   int i, j;
4049 
4050   /* Find the most used attribute value.  Handle that as the `default' of the
4051      switch we will generate.  */
4052   common_av = find_most_used (attr);
4053 
4054   /* Write out start of function, then all values with explicit `case' lines,
4055      then a `default', then the value with the most uses.  */
4056   if (attr->enum_name)
4057     fprintf (outf, "enum %s\n", attr->enum_name);
4058   else if (!attr->is_numeric)
4059     fprintf (outf, "enum attr_%s\n", attr->name);
4060   else
4061     fprintf (outf, "int\n");
4062 
4063   /* If the attribute name starts with a star, the remainder is the name of
4064      the subroutine to use, instead of `get_attr_...'.  */
4065   if (attr->name[0] == '*')
4066     fprintf (outf, "%s (rtx_insn *insn ATTRIBUTE_UNUSED)\n", &attr->name[1]);
4067   else if (attr->is_const == 0)
4068     fprintf (outf, "get_attr_%s (rtx_insn *insn ATTRIBUTE_UNUSED)\n", attr->name);
4069   else
4070     {
4071       fprintf (outf, "get_attr_%s (void)\n", attr->name);
4072       fprintf (outf, "{\n");
4073 
4074       for (av = attr->first_value; av; av = av->next)
4075 	if (av->num_insns == 1)
4076 	  write_attr_set (outf, attr, 2, av->value, "return", ";",
4077 			  true_rtx, av->first_insn->def->insn_code,
4078 			  av->first_insn->def->insn_index, 0);
4079 	else if (av->num_insns != 0)
4080 	  write_attr_set (outf, attr, 2, av->value, "return", ";",
4081 			  true_rtx, -2, 0, 0);
4082 
4083       fprintf (outf, "}\n\n");
4084       return;
4085     }
4086 
4087   fprintf (outf, "{\n");
4088 
4089   /* Find attributes that are worth caching in the conditions.  */
4090   cached_attr_count = 0;
4091   attrs_seen_more_than_once = 0;
4092   for (av = attr->first_value; av; av = av->next)
4093     {
4094       attrs_seen_once = 0;
4095       find_attrs_to_cache (av->value, true);
4096     }
4097   /* Remove those that aren't worth caching from the array.  */
4098   for (i = 0, j = 0; i < cached_attr_count; i++)
4099     if ((attrs_seen_more_than_once & (1U << i)) != 0)
4100       {
4101 	const char *name = cached_attrs[i];
4102 	class attr_desc *cached_attr;
4103 	if (i != j)
4104 	  cached_attrs[j] = name;
4105 	cached_attr = find_attr (&name, 0);
4106 	gcc_assert (cached_attr && cached_attr->is_const == 0);
4107 	if (cached_attr->enum_name)
4108 	  fprintf (outf, "  enum %s", cached_attr->enum_name);
4109 	else if (!cached_attr->is_numeric)
4110 	  fprintf (outf, "  enum attr_%s", cached_attr->name);
4111 	else
4112 	  fprintf (outf, "  int");
4113 	fprintf (outf, " cached_%s ATTRIBUTE_UNUSED;\n", name);
4114 	j++;
4115       }
4116   cached_attr_count = j;
4117   if (cached_attr_count)
4118     fprintf (outf, "\n");
4119 
4120   fprintf (outf, "  switch (recog_memoized (insn))\n");
4121   fprintf (outf, "    {\n");
4122 
4123   for (av = attr->first_value; av; av = av->next)
4124     if (av != common_av)
4125       write_attr_case (outf, attr, av, 1, "return", ";", 4, true_rtx);
4126 
4127   write_attr_case (outf, attr, common_av, 0, "return", ";", 4, true_rtx);
4128   fprintf (outf, "    }\n}\n\n");
4129   cached_attr_count = 0;
4130 }
4131 
4132 /* Given an AND tree of known true terms (because we are inside an `if' with
4133    that as the condition or are in an `else' clause) and an expression,
4134    replace any known true terms with TRUE.  Use `simplify_and_tree' to do
4135    the bulk of the work.  */
4136 
4137 static rtx
eliminate_known_true(rtx known_true,rtx exp,int insn_code,int insn_index)4138 eliminate_known_true (rtx known_true, rtx exp, int insn_code, int insn_index)
4139 {
4140   rtx term;
4141 
4142   known_true = SIMPLIFY_TEST_EXP (known_true, insn_code, insn_index);
4143 
4144   if (GET_CODE (known_true) == AND)
4145     {
4146       exp = eliminate_known_true (XEXP (known_true, 0), exp,
4147 				  insn_code, insn_index);
4148       exp = eliminate_known_true (XEXP (known_true, 1), exp,
4149 				  insn_code, insn_index);
4150     }
4151   else
4152     {
4153       term = known_true;
4154       exp = simplify_and_tree (exp, &term, insn_code, insn_index);
4155     }
4156 
4157   return exp;
4158 }
4159 
4160 /* Write out a series of tests and assignment statements to perform tests and
4161    sets of an attribute value.  We are passed an indentation amount and prefix
4162    and suffix strings to write around each attribute value (e.g., "return"
4163    and ";").  */
4164 
4165 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)4166 write_attr_set (FILE *outf, class attr_desc *attr, int indent, rtx value,
4167 		const char *prefix, const char *suffix, rtx known_true,
4168 		int insn_code, int insn_index, unsigned int attrs_cached)
4169 {
4170   if (GET_CODE (value) == COND)
4171     {
4172       /* Assume the default value will be the default of the COND unless we
4173 	 find an always true expression.  */
4174       rtx default_val = XEXP (value, 1);
4175       rtx our_known_true = known_true;
4176       rtx newexp;
4177       int first_if = 1;
4178       int i;
4179 
4180       if (cached_attr_count)
4181 	{
4182 	  attrs_seen_once = 0;
4183 	  attrs_seen_more_than_once = 0;
4184 	  for (i = 0; i < XVECLEN (value, 0); i += 2)
4185 	    find_attrs_to_cache (XVECEXP (value, 0, i), false);
4186 	  attrs_to_cache |= attrs_seen_more_than_once;
4187 	}
4188 
4189       for (i = 0; i < XVECLEN (value, 0); i += 2)
4190 	{
4191 	  rtx testexp;
4192 	  rtx inner_true;
4193 
4194 	  /* Reset our_known_true after some time to not accumulate
4195 	     too much cruft (slowing down genattrtab).  */
4196 	  if ((i & 31) == 0)
4197 	    our_known_true = known_true;
4198 	  testexp = eliminate_known_true (our_known_true,
4199 					  XVECEXP (value, 0, i),
4200 					  insn_code, insn_index);
4201 	  newexp = attr_rtx (NOT, testexp);
4202 	  newexp = insert_right_side (AND, our_known_true, newexp,
4203 				      insn_code, insn_index);
4204 
4205 	  /* If the test expression is always true or if the next `known_true'
4206 	     expression is always false, this is the last case, so break
4207 	     out and let this value be the `else' case.  */
4208 	  if (testexp == true_rtx || newexp == false_rtx)
4209 	    {
4210 	      default_val = XVECEXP (value, 0, i + 1);
4211 	      break;
4212 	    }
4213 
4214 	  /* Compute the expression to pass to our recursive call as being
4215 	     known true.  */
4216 	  inner_true = insert_right_side (AND, our_known_true,
4217 					  testexp, insn_code, insn_index);
4218 
4219 	  /* If this is always false, skip it.  */
4220 	  if (inner_true == false_rtx)
4221 	    continue;
4222 
4223 	  attrs_cached_inside = attrs_cached;
4224 	  attrs_cached_after = attrs_cached;
4225 	  write_indent (outf, indent);
4226 	  fprintf (outf, "%sif ", first_if ? "" : "else ");
4227 	  first_if = 0;
4228 	  write_test_expr (outf, testexp, attrs_cached,
4229 			   (FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND));
4230 	  attrs_cached = attrs_cached_after;
4231 	  fprintf (outf, "\n");
4232 	  write_indent (outf, indent + 2);
4233 	  fprintf (outf, "{\n");
4234 
4235 	  write_attr_set (outf, attr, indent + 4,
4236 			  XVECEXP (value, 0, i + 1), prefix, suffix,
4237 			  inner_true, insn_code, insn_index,
4238 			  attrs_cached_inside);
4239 	  write_indent (outf, indent + 2);
4240 	  fprintf (outf, "}\n");
4241 	  our_known_true = newexp;
4242 	}
4243 
4244       if (! first_if)
4245 	{
4246 	  write_indent (outf, indent);
4247 	  fprintf (outf, "else\n");
4248 	  write_indent (outf, indent + 2);
4249 	  fprintf (outf, "{\n");
4250 	}
4251 
4252       write_attr_set (outf, attr, first_if ? indent : indent + 4, default_val,
4253 		      prefix, suffix, our_known_true, insn_code, insn_index,
4254 		      attrs_cached);
4255 
4256       if (! first_if)
4257 	{
4258 	  write_indent (outf, indent + 2);
4259 	  fprintf (outf, "}\n");
4260 	}
4261     }
4262   else
4263     {
4264       write_indent (outf, indent);
4265       fprintf (outf, "%s ", prefix);
4266       write_attr_value (outf, attr, value);
4267       fprintf (outf, "%s\n", suffix);
4268     }
4269 }
4270 
4271 /* Write a series of case statements for every instruction in list IE.
4272    INDENT is the amount of indentation to write before each case.  */
4273 
4274 static void
write_insn_cases(FILE * outf,struct insn_ent * ie,int indent)4275 write_insn_cases (FILE *outf, struct insn_ent *ie, int indent)
4276 {
4277   for (; ie != 0; ie = ie->next)
4278     if (ie->def->insn_code != -1)
4279       {
4280 	write_indent (outf, indent);
4281 	if (GET_CODE (ie->def->def) == DEFINE_PEEPHOLE)
4282 	  fprintf (outf, "case %d:  /* define_peephole, %s:%d */\n",
4283 		   ie->def->insn_code, ie->def->loc.filename,
4284 		   ie->def->loc.lineno);
4285 	else
4286 	  fprintf (outf, "case %d:  /* %s */\n",
4287 		   ie->def->insn_code, XSTR (ie->def->def, 0));
4288       }
4289 }
4290 
4291 /* Write out the computation for one attribute value.  */
4292 
4293 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)4294 write_attr_case (FILE *outf, class attr_desc *attr, struct attr_value *av,
4295 		 int write_case_lines, const char *prefix, const char *suffix,
4296 		 int indent, rtx known_true)
4297 {
4298   if (av->num_insns == 0)
4299     return;
4300 
4301   if (av->has_asm_insn)
4302     {
4303       write_indent (outf, indent);
4304       fprintf (outf, "case -1:\n");
4305       write_indent (outf, indent + 2);
4306       fprintf (outf, "if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
4307       write_indent (outf, indent + 2);
4308       fprintf (outf, "    && asm_noperands (PATTERN (insn)) < 0)\n");
4309       write_indent (outf, indent + 2);
4310       fprintf (outf, "  fatal_insn_not_found (insn);\n");
4311       write_indent (outf, indent + 2);
4312       fprintf (outf, "/* FALLTHRU */\n");
4313     }
4314 
4315   if (write_case_lines)
4316     write_insn_cases (outf, av->first_insn, indent);
4317   else
4318     {
4319       write_indent (outf, indent);
4320       fprintf (outf, "default:\n");
4321     }
4322 
4323   /* See what we have to do to output this value.  */
4324   must_extract = must_constrain = address_used = 0;
4325   walk_attr_value (av->value);
4326 
4327   if (must_constrain)
4328     {
4329       write_indent (outf, indent + 2);
4330       fprintf (outf, "extract_constrain_insn_cached (insn);\n");
4331     }
4332   else if (must_extract)
4333     {
4334       write_indent (outf, indent + 2);
4335       fprintf (outf, "extract_insn_cached (insn);\n");
4336     }
4337 
4338   attrs_to_cache = 0;
4339   if (av->num_insns == 1)
4340     write_attr_set (outf, attr, indent + 2, av->value, prefix, suffix,
4341 		    known_true, av->first_insn->def->insn_code,
4342 		    av->first_insn->def->insn_index, 0);
4343   else
4344     write_attr_set (outf, attr, indent + 2, av->value, prefix, suffix,
4345 		    known_true, -2, 0, 0);
4346 
4347   if (strncmp (prefix, "return", 6))
4348     {
4349       write_indent (outf, indent + 2);
4350       fprintf (outf, "break;\n");
4351     }
4352   fprintf (outf, "\n");
4353 }
4354 
4355 /* Utilities to write in various forms.  */
4356 
4357 static void
write_attr_valueq(FILE * outf,class attr_desc * attr,const char * s)4358 write_attr_valueq (FILE *outf, class attr_desc *attr, const char *s)
4359 {
4360   if (attr->is_numeric)
4361     {
4362       int num = atoi (s);
4363 
4364       fprintf (outf, "%d", num);
4365 
4366       if (num > 9 || num < 0)
4367 	fprintf (outf, " /* %#x */", num);
4368     }
4369   else
4370     {
4371       write_upcase (outf, attr->enum_name ? attr->enum_name : attr->name);
4372       fprintf (outf, "_");
4373       write_upcase (outf, s);
4374     }
4375 }
4376 
4377 static void
write_attr_value(FILE * outf,class attr_desc * attr,rtx value)4378 write_attr_value (FILE *outf, class attr_desc *attr, rtx value)
4379 {
4380   int op;
4381 
4382   switch (GET_CODE (value))
4383     {
4384     case CONST_STRING:
4385       write_attr_valueq (outf, attr, XSTR (value, 0));
4386       break;
4387 
4388     case CONST_INT:
4389       fprintf (outf, HOST_WIDE_INT_PRINT_DEC, INTVAL (value));
4390       break;
4391 
4392     case SYMBOL_REF:
4393       rtx_reader_ptr->fprint_c_condition (outf, XSTR (value, 0));
4394       break;
4395 
4396     case ATTR:
4397       {
4398 	class attr_desc *attr2 = find_attr (&XSTR (value, 0), 0);
4399 	if (attr->enum_name)
4400 	  fprintf (outf, "(enum %s)", attr->enum_name);
4401 	else if (!attr->is_numeric)
4402 	  fprintf (outf, "(enum attr_%s)", attr->name);
4403 	else if (!attr2->is_numeric)
4404 	  fprintf (outf, "(int)");
4405 
4406 	fprintf (outf, "get_attr_%s (%s)", attr2->name,
4407 		 (attr2->is_const ? "" : "insn"));
4408       }
4409       break;
4410 
4411     case PLUS:
4412       op = '+';
4413       goto do_operator;
4414     case MINUS:
4415       op = '-';
4416       goto do_operator;
4417     case MULT:
4418       op = '*';
4419       goto do_operator;
4420     case DIV:
4421       op = '/';
4422       goto do_operator;
4423     case MOD:
4424       op = '%';
4425       goto do_operator;
4426 
4427     do_operator:
4428       fprintf (outf, "(");
4429       write_attr_value (outf, attr, XEXP (value, 0));
4430       fprintf (outf, " %c ", op);
4431       write_attr_value (outf, attr, XEXP (value, 1));
4432       fprintf (outf, ")");
4433       break;
4434 
4435     case IF_THEN_ELSE:
4436       fprintf (outf, "(");
4437       write_test_expr (outf, XEXP (value, 0), 0, 0, false);
4438       fprintf (outf, " ? ");
4439       write_attr_value (outf, attr, XEXP (value, 1));
4440       fprintf (outf, " : ");
4441       write_attr_value (outf, attr, XEXP (value, 2));
4442       fprintf (outf, ")");
4443       break;
4444 
4445     default:
4446       gcc_unreachable ();
4447     }
4448 }
4449 
4450 static void
write_upcase(FILE * outf,const char * str)4451 write_upcase (FILE *outf, const char *str)
4452 {
4453   while (*str)
4454     {
4455       /* The argument of TOUPPER should not have side effects.  */
4456       fputc (TOUPPER (*str), outf);
4457       str++;
4458     }
4459 }
4460 
4461 static void
write_indent(FILE * outf,int indent)4462 write_indent (FILE *outf, int indent)
4463 {
4464   for (; indent > 8; indent -= 8)
4465     fprintf (outf, "\t");
4466 
4467   for (; indent; indent--)
4468     fprintf (outf, " ");
4469 }
4470 
4471 /* If the target does not have annul-true or annul-false delay slots, this
4472    function will create a dummy eligible_for function on OUTF which always
4473    returns false.  KIND will be annul_true or annul_false.  */
4474 
4475 static void
write_dummy_eligible_delay(FILE * outf,const char * kind)4476 write_dummy_eligible_delay (FILE *outf, const char *kind)
4477 {
4478   /* Write function prelude.  */
4479 
4480   fprintf (outf, "int\n");
4481   fprintf (outf, "eligible_for_%s (rtx_insn *delay_insn ATTRIBUTE_UNUSED,\n"
4482 		 "    int slot ATTRIBUTE_UNUSED,\n"
4483 		 "    rtx_insn *candidate_insn ATTRIBUTE_UNUSED,\n"
4484 		 "    int flags ATTRIBUTE_UNUSED)\n",
4485 	   kind);
4486   fprintf (outf, "{\n");
4487   fprintf (outf, "  return 0;\n");
4488   fprintf (outf, "}\n\n");
4489 }
4490 
4491 /* Write a subroutine that is given an insn that requires a delay slot, a
4492    delay slot ordinal, and a candidate insn.  It returns nonzero if the
4493    candidate can be placed in the specified delay slot of the insn.
4494 
4495    We can write as many as three subroutines.  `eligible_for_delay'
4496    handles normal delay slots, `eligible_for_annul_true' indicates that
4497    the specified insn can be annulled if the branch is true, and likewise
4498    for `eligible_for_annul_false'.
4499 
4500    KIND is a string distinguishing these three cases ("delay", "annul_true",
4501    or "annul_false").  */
4502 
4503 static void
write_eligible_delay(FILE * outf,const char * kind)4504 write_eligible_delay (FILE *outf, const char *kind)
4505 {
4506   class delay_desc *delay;
4507   int max_slots;
4508   char str[50];
4509   const char *pstr;
4510   class attr_desc *attr;
4511   struct attr_value *av, *common_av;
4512   int i;
4513 
4514   /* Compute the maximum number of delay slots required.  We use the delay
4515      ordinal times this number plus one, plus the slot number as an index into
4516      the appropriate predicate to test.  */
4517 
4518   for (delay = delays, max_slots = 0; delay; delay = delay->next)
4519     if (XVECLEN (delay->def, 1) / 3 > max_slots)
4520       max_slots = XVECLEN (delay->def, 1) / 3;
4521 
4522   /* Write function prelude.  */
4523 
4524   fprintf (outf, "int\n");
4525   fprintf (outf, "eligible_for_%s (rtx_insn *delay_insn ATTRIBUTE_UNUSED, int slot, \n"
4526 		 "		   rtx_insn *candidate_insn, int flags ATTRIBUTE_UNUSED)\n",
4527 	   kind);
4528   fprintf (outf, "{\n");
4529   fprintf (outf, "  rtx_insn *insn ATTRIBUTE_UNUSED;\n");
4530   fprintf (outf, "\n");
4531   fprintf (outf, "  if (num_delay_slots (delay_insn) == 0)\n");
4532   fprintf (outf, "    return 0;");
4533   fprintf (outf, "\n");
4534   fprintf (outf, "  gcc_assert (slot < %d);\n", max_slots);
4535   fprintf (outf, "\n");
4536   /* Allow dbr_schedule to pass labels, etc.  This can happen if try_split
4537      converts a compound instruction into a loop.  */
4538   fprintf (outf, "  if (!INSN_P (candidate_insn))\n");
4539   fprintf (outf, "    return 0;\n");
4540   fprintf (outf, "\n");
4541 
4542   /* If more than one delay type, find out which type the delay insn is.  */
4543 
4544   if (num_delays > 1)
4545     {
4546       attr = find_attr (&delay_type_str, 0);
4547       gcc_assert (attr);
4548       common_av = find_most_used (attr);
4549 
4550       fprintf (outf, "  insn = delay_insn;\n");
4551       fprintf (outf, "  switch (recog_memoized (insn))\n");
4552       fprintf (outf, "    {\n");
4553 
4554       sprintf (str, " * %d;\n      break;", max_slots);
4555       for (av = attr->first_value; av; av = av->next)
4556 	if (av != common_av)
4557 	  write_attr_case (outf, attr, av, 1, "slot +=", str, 4, true_rtx);
4558 
4559       write_attr_case (outf, attr, common_av, 0, "slot +=", str, 4, true_rtx);
4560       fprintf (outf, "    }\n\n");
4561 
4562       /* Ensure matched.  Otherwise, shouldn't have been called.  */
4563       fprintf (outf, "  gcc_assert (slot >= %d);\n\n", max_slots);
4564     }
4565 
4566   /* If just one type of delay slot, write simple switch.  */
4567   if (num_delays == 1 && max_slots == 1)
4568     {
4569       fprintf (outf, "  insn = candidate_insn;\n");
4570       fprintf (outf, "  switch (recog_memoized (insn))\n");
4571       fprintf (outf, "    {\n");
4572 
4573       attr = find_attr (&delay_1_0_str, 0);
4574       gcc_assert (attr);
4575       common_av = find_most_used (attr);
4576 
4577       for (av = attr->first_value; av; av = av->next)
4578 	if (av != common_av)
4579 	  write_attr_case (outf, attr, av, 1, "return", ";", 4, true_rtx);
4580 
4581       write_attr_case (outf, attr, common_av, 0, "return", ";", 4, true_rtx);
4582       fprintf (outf, "    }\n");
4583     }
4584 
4585   else
4586     {
4587       /* Write a nested CASE.  The first indicates which condition we need to
4588 	 test, and the inner CASE tests the condition.  */
4589       fprintf (outf, "  insn = candidate_insn;\n");
4590       fprintf (outf, "  switch (slot)\n");
4591       fprintf (outf, "    {\n");
4592 
4593       for (delay = delays; delay; delay = delay->next)
4594 	for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
4595 	  {
4596 	    fprintf (outf, "    case %d:\n",
4597 		     (i / 3) + (num_delays == 1 ? 0 : delay->num * max_slots));
4598 	    fprintf (outf, "      switch (recog_memoized (insn))\n");
4599 	    fprintf (outf, "\t{\n");
4600 
4601 	    sprintf (str, "*%s_%d_%d", kind, delay->num, i / 3);
4602 	    pstr = str;
4603 	    attr = find_attr (&pstr, 0);
4604 	    gcc_assert (attr);
4605 	    common_av = find_most_used (attr);
4606 
4607 	    for (av = attr->first_value; av; av = av->next)
4608 	      if (av != common_av)
4609 		write_attr_case (outf, attr, av, 1, "return", ";", 8, true_rtx);
4610 
4611 	    write_attr_case (outf, attr, common_av, 0, "return", ";", 8, true_rtx);
4612 	    fprintf (outf, "      }\n");
4613 	  }
4614 
4615       fprintf (outf, "    default:\n");
4616       fprintf (outf, "      gcc_unreachable ();\n");
4617       fprintf (outf, "    }\n");
4618     }
4619 
4620   fprintf (outf, "}\n\n");
4621 }
4622 
4623 /* This page contains miscellaneous utility routines.  */
4624 
4625 /* Given a pointer to a (char *), return a malloc'ed string containing the
4626    next comma-separated element.  Advance the pointer to after the string
4627    scanned, or the end-of-string.  Return NULL if at end of string.  */
4628 
4629 static char *
next_comma_elt(const char ** pstr)4630 next_comma_elt (const char **pstr)
4631 {
4632   const char *start;
4633 
4634   start = scan_comma_elt (pstr);
4635 
4636   if (start == NULL)
4637     return NULL;
4638 
4639   return attr_string (start, *pstr - start);
4640 }
4641 
4642 /* Return a `class attr_desc' pointer for a given named attribute.  If CREATE
4643    is nonzero, build a new attribute, if one does not exist.  *NAME_P is
4644    replaced by a pointer to a canonical copy of the string.  */
4645 
4646 static class attr_desc *
find_attr(const char ** name_p,int create)4647 find_attr (const char **name_p, int create)
4648 {
4649   class attr_desc *attr;
4650   int index;
4651   const char *name = *name_p;
4652 
4653   /* Before we resort to using `strcmp', see if the string address matches
4654      anywhere.  In most cases, it should have been canonicalized to do so.  */
4655   if (name == alternative_name)
4656     return NULL;
4657 
4658   index = name[0] & (MAX_ATTRS_INDEX - 1);
4659   for (attr = attrs[index]; attr; attr = attr->next)
4660     if (name == attr->name)
4661       return attr;
4662 
4663   /* Otherwise, do it the slow way.  */
4664   for (attr = attrs[index]; attr; attr = attr->next)
4665     if (name[0] == attr->name[0] && ! strcmp (name, attr->name))
4666       {
4667 	*name_p = attr->name;
4668 	return attr;
4669       }
4670 
4671   if (! create)
4672     return NULL;
4673 
4674   attr = oballoc (class attr_desc);
4675   attr->name = DEF_ATTR_STRING (name);
4676   attr->enum_name = 0;
4677   attr->first_value = attr->default_val = NULL;
4678   attr->is_numeric = attr->is_const = attr->is_special = 0;
4679   attr->next = attrs[index];
4680   attrs[index] = attr;
4681 
4682   *name_p = attr->name;
4683 
4684   return attr;
4685 }
4686 
4687 /* Create internal attribute with the given default value.  */
4688 
4689 static void
make_internal_attr(const char * name,rtx value,int special)4690 make_internal_attr (const char *name, rtx value, int special)
4691 {
4692   class attr_desc *attr;
4693 
4694   attr = find_attr (&name, 1);
4695   gcc_assert (!attr->default_val);
4696 
4697   attr->is_numeric = 1;
4698   attr->is_const = 0;
4699   attr->is_special = (special & ATTR_SPECIAL) != 0;
4700   attr->default_val = get_attr_value (file_location ("<internal>", 0, 0),
4701 				      value, attr, -2);
4702 }
4703 
4704 /* Find the most used value of an attribute.  */
4705 
4706 static struct attr_value *
find_most_used(class attr_desc * attr)4707 find_most_used (class attr_desc *attr)
4708 {
4709   struct attr_value *av;
4710   struct attr_value *most_used;
4711   int nuses;
4712 
4713   most_used = NULL;
4714   nuses = -1;
4715 
4716   for (av = attr->first_value; av; av = av->next)
4717     if (av->num_insns > nuses)
4718       nuses = av->num_insns, most_used = av;
4719 
4720   return most_used;
4721 }
4722 
4723 /* Return (attr_value "n") */
4724 
4725 static rtx
make_numeric_value(int n)4726 make_numeric_value (int n)
4727 {
4728   static rtx int_values[20];
4729   rtx exp;
4730   char *p;
4731 
4732   gcc_assert (n >= 0);
4733 
4734   if (n < 20 && int_values[n])
4735     return int_values[n];
4736 
4737   p = attr_printf (MAX_DIGITS, "%d", n);
4738   exp = attr_rtx (CONST_STRING, p);
4739 
4740   if (n < 20)
4741     int_values[n] = exp;
4742 
4743   return exp;
4744 }
4745 
4746 static rtx
copy_rtx_unchanging(rtx orig)4747 copy_rtx_unchanging (rtx orig)
4748 {
4749   if (ATTR_IND_SIMPLIFIED_P (orig) || ATTR_CURR_SIMPLIFIED_P (orig))
4750     return orig;
4751 
4752   ATTR_CURR_SIMPLIFIED_P (orig) = 1;
4753   return orig;
4754 }
4755 
4756 /* Determine if an insn has a constant number of delay slots, i.e., the
4757    number of delay slots is not a function of the length of the insn.  */
4758 
4759 static void
write_const_num_delay_slots(FILE * outf)4760 write_const_num_delay_slots (FILE *outf)
4761 {
4762   class attr_desc *attr = find_attr (&num_delay_slots_str, 0);
4763   struct attr_value *av;
4764 
4765   if (attr)
4766     {
4767       fprintf (outf, "int\nconst_num_delay_slots (rtx_insn *insn)\n");
4768       fprintf (outf, "{\n");
4769       fprintf (outf, "  switch (recog_memoized (insn))\n");
4770       fprintf (outf, "    {\n");
4771 
4772       for (av = attr->first_value; av; av = av->next)
4773 	{
4774 	  length_used = 0;
4775 	  walk_attr_value (av->value);
4776 	  if (length_used)
4777 	    write_insn_cases (outf, av->first_insn, 4);
4778 	}
4779 
4780       fprintf (outf, "    default:\n");
4781       fprintf (outf, "      return 1;\n");
4782       fprintf (outf, "    }\n}\n\n");
4783     }
4784 }
4785 
4786 /* Synthetic attributes used by insn-automata.c and the scheduler.
4787    These are primarily concerned with (define_insn_reservation)
4788    patterns.  */
4789 
4790 struct insn_reserv
4791 {
4792   struct insn_reserv *next;
4793 
4794   const char *name;
4795   int default_latency;
4796   rtx condexp;
4797 
4798   /* Sequence number of this insn.  */
4799   int insn_num;
4800 
4801   /* Whether a (define_bypass) construct names this insn in its
4802      output list.  */
4803   bool bypassed;
4804 };
4805 
4806 static struct insn_reserv *all_insn_reservs = 0;
4807 static struct insn_reserv **last_insn_reserv_p = &all_insn_reservs;
4808 static size_t n_insn_reservs;
4809 
4810 /* Store information from a DEFINE_INSN_RESERVATION for future
4811    attribute generation.  */
4812 static void
gen_insn_reserv(md_rtx_info * info)4813 gen_insn_reserv (md_rtx_info *info)
4814 {
4815   struct insn_reserv *decl = oballoc (struct insn_reserv);
4816   rtx def = info->def;
4817 
4818   class attr_desc attr = { };
4819 
4820   attr.name = DEF_ATTR_STRING (XSTR (def, 0));
4821   attr.loc = info->loc;
4822 
4823   decl->name            = DEF_ATTR_STRING (XSTR (def, 0));
4824   decl->default_latency = XINT (def, 1);
4825   decl->condexp         = check_attr_test (info->loc, XEXP (def, 2), &attr);
4826   decl->insn_num        = n_insn_reservs;
4827   decl->bypassed	= false;
4828   decl->next            = 0;
4829 
4830   *last_insn_reserv_p = decl;
4831   last_insn_reserv_p  = &decl->next;
4832   n_insn_reservs++;
4833 }
4834 
4835 /* Store information from a DEFINE_BYPASS for future attribute
4836    generation.  The only thing we care about is the list of output
4837    insns, which will later be used to tag reservation structures with
4838    a 'bypassed' bit.  */
4839 
4840 struct bypass_list
4841 {
4842   struct bypass_list *next;
4843   const char *pattern;
4844 };
4845 
4846 static struct bypass_list *all_bypasses;
4847 static size_t n_bypasses;
4848 static size_t n_bypassed;
4849 
4850 static void
gen_bypass_1(const char * s,size_t len)4851 gen_bypass_1 (const char *s, size_t len)
4852 {
4853   struct bypass_list *b;
4854 
4855   if (len == 0)
4856     return;
4857 
4858   s = attr_string (s, len);
4859   for (b = all_bypasses; b; b = b->next)
4860     if (s == b->pattern)
4861       return;  /* already got that one */
4862 
4863   b = oballoc (struct bypass_list);
4864   b->pattern = s;
4865   b->next = all_bypasses;
4866   all_bypasses = b;
4867   n_bypasses++;
4868 }
4869 
4870 static void
gen_bypass(md_rtx_info * info)4871 gen_bypass (md_rtx_info *info)
4872 {
4873   const char *p, *base;
4874 
4875   rtx def = info->def;
4876   for (p = base = XSTR (def, 1); *p; p++)
4877     if (*p == ',')
4878       {
4879 	gen_bypass_1 (base, p - base);
4880 	do
4881 	  p++;
4882 	while (ISSPACE (*p));
4883 	base = p;
4884       }
4885   gen_bypass_1 (base, p - base);
4886 }
4887 
4888 /* Find and mark all of the bypassed insns.  */
4889 static void
process_bypasses(void)4890 process_bypasses (void)
4891 {
4892   struct bypass_list *b;
4893   struct insn_reserv *r;
4894 
4895   n_bypassed = 0;
4896 
4897   /* The reservation list is likely to be much longer than the bypass
4898      list.  */
4899   for (r = all_insn_reservs; r; r = r->next)
4900     for (b = all_bypasses; b; b = b->next)
4901       if (fnmatch (b->pattern, r->name, 0) == 0)
4902         {
4903           n_bypassed++;
4904           r->bypassed = true;
4905           break;
4906         }
4907 }
4908 
4909 /* Check that attribute NAME is used in define_insn_reservation condition
4910    EXP.  Return true if it is.  */
4911 static bool
check_tune_attr(const char * name,rtx exp)4912 check_tune_attr (const char *name, rtx exp)
4913 {
4914   switch (GET_CODE (exp))
4915     {
4916     case AND:
4917       if (check_tune_attr (name, XEXP (exp, 0)))
4918 	return true;
4919       return check_tune_attr (name, XEXP (exp, 1));
4920 
4921     case IOR:
4922       return (check_tune_attr (name, XEXP (exp, 0))
4923 	      && check_tune_attr (name, XEXP (exp, 1)));
4924 
4925     case EQ_ATTR:
4926       return XSTR (exp, 0) == name;
4927 
4928     default:
4929       return false;
4930     }
4931 }
4932 
4933 /* Try to find a const attribute (usually cpu or tune) that is used
4934    in all define_insn_reservation conditions.  */
4935 static class attr_desc *
find_tune_attr(rtx exp)4936 find_tune_attr (rtx exp)
4937 {
4938   class attr_desc *attr;
4939 
4940   switch (GET_CODE (exp))
4941     {
4942     case AND:
4943     case IOR:
4944       attr = find_tune_attr (XEXP (exp, 0));
4945       if (attr)
4946 	return attr;
4947       return find_tune_attr (XEXP (exp, 1));
4948 
4949     case EQ_ATTR:
4950       if (XSTR (exp, 0) == alternative_name)
4951 	return NULL;
4952 
4953       attr = find_attr (&XSTR (exp, 0), 0);
4954       gcc_assert (attr);
4955 
4956       if (attr->is_const && !attr->is_special)
4957 	{
4958 	  struct insn_reserv *decl;
4959 
4960 	  for (decl = all_insn_reservs; decl; decl = decl->next)
4961 	    if (! check_tune_attr (attr->name, decl->condexp))
4962 	      return NULL;
4963 	  return attr;
4964 	}
4965       return NULL;
4966 
4967     default:
4968       return NULL;
4969     }
4970 }
4971 
4972 /* Create all of the attributes that describe automaton properties.
4973    Write the DFA and latency function prototypes to  the files that
4974    need to have them, and write the init_sched_attrs().  */
4975 
4976 static void
make_automaton_attrs(void)4977 make_automaton_attrs (void)
4978 {
4979   int i;
4980   struct insn_reserv *decl;
4981   rtx code_exp, lats_exp, byps_exp;
4982   class attr_desc *tune_attr;
4983 
4984   if (n_insn_reservs == 0)
4985     return;
4986 
4987   tune_attr = find_tune_attr (all_insn_reservs->condexp);
4988   if (tune_attr != NULL)
4989     {
4990       rtx *condexps = XNEWVEC (rtx, n_insn_reservs * 3);
4991       struct attr_value *val;
4992       bool first = true;
4993 
4994       gcc_assert (tune_attr->is_const
4995 		  && !tune_attr->is_special
4996 		  && !tune_attr->is_numeric);
4997 
4998       /* Write the prototypes for all DFA functions.  */
4999       for (val = tune_attr->first_value; val; val = val->next)
5000 	{
5001 	  if (val == tune_attr->default_val)
5002 	    continue;
5003 	  gcc_assert (GET_CODE (val->value) == CONST_STRING);
5004 	  fprintf (dfa_file,
5005 		   "extern int internal_dfa_insn_code_%s (rtx_insn *);\n",
5006 		   XSTR (val->value, 0));
5007 	}
5008       fprintf (dfa_file, "\n");
5009 
5010       /* Write the prototypes for all latency functions.  */
5011       for (val = tune_attr->first_value; val; val = val->next)
5012 	{
5013 	  if (val == tune_attr->default_val)
5014 	    continue;
5015 	  gcc_assert (GET_CODE (val->value) == CONST_STRING);
5016 	  fprintf (latency_file,
5017 		   "extern int insn_default_latency_%s (rtx_insn *);\n",
5018 		   XSTR (val->value, 0));
5019 	}
5020       fprintf (latency_file, "\n");
5021 
5022       /* Write the prototypes for all automaton functions.  */
5023       for (val = tune_attr->first_value; val; val = val->next)
5024 	{
5025 	  if (val == tune_attr->default_val)
5026 	    continue;
5027 	  gcc_assert (GET_CODE (val->value) == CONST_STRING);
5028 	  fprintf (attr_file,
5029 		   "extern int internal_dfa_insn_code_%s (rtx_insn *);\n"
5030 		   "extern int insn_default_latency_%s (rtx_insn *);\n",
5031 		   XSTR (val->value, 0), XSTR (val->value, 0));
5032 	}
5033       fprintf (attr_file, "\n");
5034       fprintf (attr_file, "int (*internal_dfa_insn_code) (rtx_insn *);\n");
5035       fprintf (attr_file, "int (*insn_default_latency) (rtx_insn *);\n");
5036       fprintf (attr_file, "\n");
5037       fprintf (attr_file, "void\n");
5038       fprintf (attr_file, "init_sched_attrs (void)\n");
5039       fprintf (attr_file, "{\n");
5040 
5041       for (val = tune_attr->first_value; val; val = val->next)
5042 	{
5043 	  int j;
5044 	  char *name;
5045 	  rtx test = attr_eq (tune_attr->name, XSTR (val->value, 0));
5046 
5047 	  if (val == tune_attr->default_val)
5048 	    continue;
5049 	  for (decl = all_insn_reservs, i = 0;
5050 	       decl;
5051 	       decl = decl->next)
5052 	    {
5053 	      rtx ctest = test;
5054 	      rtx condexp
5055 		= simplify_and_tree (decl->condexp, &ctest, -2, 0);
5056 	      if (condexp == false_rtx)
5057 		continue;
5058 	      if (condexp == true_rtx)
5059 		break;
5060 	      condexps[i] = condexp;
5061 	      condexps[i + 1] = make_numeric_value (decl->insn_num);
5062 	      condexps[i + 2] = make_numeric_value (decl->default_latency);
5063 	      i += 3;
5064 	    }
5065 
5066 	  code_exp = rtx_alloc (COND);
5067 	  lats_exp = rtx_alloc (COND);
5068 
5069 	  j = i / 3 * 2;
5070 	  XVEC (code_exp, 0) = rtvec_alloc (j);
5071 	  XVEC (lats_exp, 0) = rtvec_alloc (j);
5072 
5073 	  if (decl)
5074 	    {
5075 	      XEXP (code_exp, 1) = make_numeric_value (decl->insn_num);
5076 	      XEXP (lats_exp, 1) = make_numeric_value (decl->default_latency);
5077 	    }
5078 	  else
5079 	    {
5080 	      XEXP (code_exp, 1) = make_numeric_value (n_insn_reservs + 1);
5081 	      XEXP (lats_exp, 1) = make_numeric_value (0);
5082 	    }
5083 
5084 	  while (i > 0)
5085 	    {
5086 	      i -= 3;
5087 	      j -= 2;
5088 	      XVECEXP (code_exp, 0, j) = condexps[i];
5089 	      XVECEXP (lats_exp, 0, j) = condexps[i];
5090 
5091 	      XVECEXP (code_exp, 0, j + 1) = condexps[i + 1];
5092 	      XVECEXP (lats_exp, 0, j + 1) = condexps[i + 2];
5093 	    }
5094 
5095 	  name = XNEWVEC (char,
5096 			  sizeof ("*internal_dfa_insn_code_")
5097 			  + strlen (XSTR (val->value, 0)));
5098 	  strcpy (name, "*internal_dfa_insn_code_");
5099 	  strcat (name, XSTR (val->value, 0));
5100 	  make_internal_attr (name, code_exp, ATTR_NONE);
5101 	  strcpy (name, "*insn_default_latency_");
5102 	  strcat (name, XSTR (val->value, 0));
5103 	  make_internal_attr (name, lats_exp, ATTR_NONE);
5104 	  XDELETEVEC (name);
5105 
5106 	  if (first)
5107 	    {
5108 	      fprintf (attr_file, "  if (");
5109 	      first = false;
5110 	    }
5111 	  else
5112 	    fprintf (attr_file, "  else if (");
5113 	  write_test_expr (attr_file, test, 0, 0);
5114 	  fprintf (attr_file, ")\n");
5115 	  fprintf (attr_file, "    {\n");
5116 	  fprintf (attr_file, "      internal_dfa_insn_code\n");
5117 	  fprintf (attr_file, "        = internal_dfa_insn_code_%s;\n",
5118 		   XSTR (val->value, 0));
5119 	  fprintf (attr_file, "      insn_default_latency\n");
5120 	  fprintf (attr_file, "        = insn_default_latency_%s;\n",
5121 		   XSTR (val->value, 0));
5122 	  fprintf (attr_file, "    }\n");
5123 	}
5124 
5125       fprintf (attr_file, "  else\n");
5126       fprintf (attr_file, "    gcc_unreachable ();\n");
5127       fprintf (attr_file, "}\n");
5128       fprintf (attr_file, "\n");
5129 
5130       XDELETEVEC (condexps);
5131     }
5132   else
5133     {
5134       code_exp = rtx_alloc (COND);
5135       lats_exp = rtx_alloc (COND);
5136 
5137       XVEC (code_exp, 0) = rtvec_alloc (n_insn_reservs * 2);
5138       XVEC (lats_exp, 0) = rtvec_alloc (n_insn_reservs * 2);
5139 
5140       XEXP (code_exp, 1) = make_numeric_value (n_insn_reservs + 1);
5141       XEXP (lats_exp, 1) = make_numeric_value (0);
5142 
5143       for (decl = all_insn_reservs, i = 0;
5144 	   decl;
5145 	   decl = decl->next, i += 2)
5146 	{
5147 	  XVECEXP (code_exp, 0, i)   = decl->condexp;
5148 	  XVECEXP (lats_exp, 0, i)   = decl->condexp;
5149 
5150 	  XVECEXP (code_exp, 0, i+1) = make_numeric_value (decl->insn_num);
5151 	  XVECEXP (lats_exp, 0, i+1)
5152 	    = make_numeric_value (decl->default_latency);
5153 	}
5154       make_internal_attr ("*internal_dfa_insn_code", code_exp, ATTR_NONE);
5155       make_internal_attr ("*insn_default_latency",   lats_exp, ATTR_NONE);
5156     }
5157 
5158   if (n_bypasses == 0)
5159     byps_exp = make_numeric_value (0);
5160   else
5161     {
5162       process_bypasses ();
5163 
5164       byps_exp = rtx_alloc (COND);
5165       XVEC (byps_exp, 0) = rtvec_alloc (n_bypassed * 2);
5166       XEXP (byps_exp, 1) = make_numeric_value (0);
5167       for (decl = all_insn_reservs, i = 0;
5168 	   decl;
5169 	   decl = decl->next)
5170 	if (decl->bypassed)
5171 	  {
5172 	    XVECEXP (byps_exp, 0, i)   = decl->condexp;
5173 	    XVECEXP (byps_exp, 0, i+1) = make_numeric_value (1);
5174 	    i += 2;
5175 	  }
5176     }
5177 
5178   make_internal_attr ("*bypass_p", byps_exp, ATTR_NONE);
5179 }
5180 
5181 static void
write_header(FILE * outf)5182 write_header (FILE *outf)
5183 {
5184   fprintf (outf, "/* Generated automatically by the program `genattrtab'\n"
5185 	         "   from the machine description file `md'.  */\n\n");
5186 
5187   fprintf (outf, "#define IN_TARGET_CODE 1\n");
5188   fprintf (outf, "#include \"config.h\"\n");
5189   fprintf (outf, "#include \"system.h\"\n");
5190   fprintf (outf, "#include \"coretypes.h\"\n");
5191   fprintf (outf, "#include \"backend.h\"\n");
5192   fprintf (outf, "#include \"predict.h\"\n");
5193   fprintf (outf, "#include \"tree.h\"\n");
5194   fprintf (outf, "#include \"rtl.h\"\n");
5195   fprintf (outf, "#include \"alias.h\"\n");
5196   fprintf (outf, "#include \"options.h\"\n");
5197   fprintf (outf, "#include \"varasm.h\"\n");
5198   fprintf (outf, "#include \"stor-layout.h\"\n");
5199   fprintf (outf, "#include \"calls.h\"\n");
5200   fprintf (outf, "#include \"insn-attr.h\"\n");
5201   fprintf (outf, "#include \"memmodel.h\"\n");
5202   fprintf (outf, "#include \"tm_p.h\"\n");
5203   fprintf (outf, "#include \"insn-config.h\"\n");
5204   fprintf (outf, "#include \"recog.h\"\n");
5205   fprintf (outf, "#include \"regs.h\"\n");
5206   fprintf (outf, "#include \"real.h\"\n");
5207   fprintf (outf, "#include \"output.h\"\n");
5208   fprintf (outf, "#include \"toplev.h\"\n");
5209   fprintf (outf, "#include \"flags.h\"\n");
5210   fprintf (outf, "#include \"emit-rtl.h\"\n");
5211   fprintf (outf, "\n");
5212   fprintf (outf, "#define operands recog_data.operand\n\n");
5213 }
5214 
5215 static FILE *
open_outfile(const char * file_name)5216 open_outfile (const char *file_name)
5217 {
5218   FILE *outf;
5219   outf = fopen (file_name, "w");
5220   if (! outf)
5221     fatal ("cannot open file %s: %s", file_name, xstrerror (errno));
5222   write_header (outf);
5223   return outf;
5224 }
5225 
5226 static bool
handle_arg(const char * arg)5227 handle_arg (const char *arg)
5228 {
5229   switch (arg[1])
5230     {
5231     case 'A':
5232       attr_file_name = &arg[2];
5233       return true;
5234     case 'D':
5235       dfa_file_name = &arg[2];
5236       return true;
5237     case 'L':
5238       latency_file_name = &arg[2];
5239       return true;
5240     default:
5241       return false;
5242     }
5243 }
5244 
5245 int
main(int argc,const char ** argv)5246 main (int argc, const char **argv)
5247 {
5248   class attr_desc *attr;
5249   class insn_def *id;
5250   int i;
5251 
5252   progname = "genattrtab";
5253 
5254   if (!init_rtx_reader_args_cb (argc, argv, handle_arg))
5255     return FATAL_EXIT_CODE;
5256 
5257   attr_file = open_outfile (attr_file_name);
5258   dfa_file = open_outfile (dfa_file_name);
5259   latency_file = open_outfile (latency_file_name);
5260 
5261   obstack_init (hash_obstack);
5262   obstack_init (temp_obstack);
5263 
5264   /* Set up true and false rtx's */
5265   true_rtx = rtx_alloc (CONST_INT);
5266   XWINT (true_rtx, 0) = 1;
5267   false_rtx = rtx_alloc (CONST_INT);
5268   XWINT (false_rtx, 0) = 0;
5269   ATTR_IND_SIMPLIFIED_P (true_rtx) = ATTR_IND_SIMPLIFIED_P (false_rtx) = 1;
5270   ATTR_PERMANENT_P (true_rtx) = ATTR_PERMANENT_P (false_rtx) = 1;
5271 
5272   alternative_name = DEF_ATTR_STRING ("alternative");
5273   length_str = DEF_ATTR_STRING ("length");
5274   delay_type_str = DEF_ATTR_STRING ("*delay_type");
5275   delay_1_0_str = DEF_ATTR_STRING ("*delay_1_0");
5276   num_delay_slots_str = DEF_ATTR_STRING ("*num_delay_slots");
5277 
5278   /* Read the machine description.  */
5279 
5280   md_rtx_info info;
5281   while (read_md_rtx (&info))
5282     {
5283       switch (GET_CODE (info.def))
5284 	{
5285 	case DEFINE_INSN:
5286 	case DEFINE_PEEPHOLE:
5287 	case DEFINE_ASM_ATTRIBUTES:
5288 	  gen_insn (&info);
5289 	  break;
5290 
5291 	case DEFINE_ATTR:
5292 	case DEFINE_ENUM_ATTR:
5293 	  gen_attr (&info);
5294 	  break;
5295 
5296 	case DEFINE_DELAY:
5297 	  gen_delay (&info);
5298 	  break;
5299 
5300 	case DEFINE_INSN_RESERVATION:
5301 	  gen_insn_reserv (&info);
5302 	  break;
5303 
5304 	case DEFINE_BYPASS:
5305 	  gen_bypass (&info);
5306 	  break;
5307 
5308 	default:
5309 	  break;
5310 	}
5311       if (GET_CODE (info.def) != DEFINE_ASM_ATTRIBUTES)
5312 	insn_index_number++;
5313     }
5314 
5315   if (have_error)
5316     return FATAL_EXIT_CODE;
5317 
5318   /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one.  */
5319   if (! got_define_asm_attributes)
5320     {
5321       md_rtx_info info;
5322       info.def = rtx_alloc (DEFINE_ASM_ATTRIBUTES);
5323       XVEC (info.def, 0) = rtvec_alloc (0);
5324       info.loc = file_location ("<internal>", 0, 0);
5325       info.index = -1;
5326       gen_insn (&info);
5327     }
5328 
5329   /* Expand DEFINE_DELAY information into new attribute.  */
5330   expand_delays ();
5331 
5332   /* Make `insn_alternatives'.  */
5333   int num_insn_codes = get_num_insn_codes ();
5334   insn_alternatives = oballocvec (alternative_mask, num_insn_codes);
5335   for (id = defs; id; id = id->next)
5336     if (id->insn_code >= 0)
5337       insn_alternatives[id->insn_code]
5338 	= (((alternative_mask) 1) << id->num_alternatives) - 1;
5339 
5340   /* Make `insn_n_alternatives'.  */
5341   insn_n_alternatives = oballocvec (int, num_insn_codes);
5342   for (id = defs; id; id = id->next)
5343     if (id->insn_code >= 0)
5344       insn_n_alternatives[id->insn_code] = id->num_alternatives;
5345 
5346   /* Construct extra attributes for automata.  */
5347   make_automaton_attrs ();
5348 
5349   /* Prepare to write out attribute subroutines by checking everything stored
5350      away and building the attribute cases.  */
5351 
5352   check_defs ();
5353 
5354   for (i = 0; i < MAX_ATTRS_INDEX; i++)
5355     for (attr = attrs[i]; attr; attr = attr->next)
5356       attr->default_val->value
5357 	= check_attr_value (attr->loc, attr->default_val->value, attr);
5358 
5359   if (have_error)
5360     return FATAL_EXIT_CODE;
5361 
5362   for (i = 0; i < MAX_ATTRS_INDEX; i++)
5363     for (attr = attrs[i]; attr; attr = attr->next)
5364       fill_attr (attr);
5365 
5366   /* Construct extra attributes for `length'.  */
5367   make_length_attrs ();
5368 
5369   /* Perform any possible optimizations to speed up compilation.  */
5370   optimize_attrs (num_insn_codes);
5371 
5372   /* Now write out all the `gen_attr_...' routines.  Do these before the
5373      special routines so that they get defined before they are used.  */
5374 
5375   for (i = 0; i < MAX_ATTRS_INDEX; i++)
5376     for (attr = attrs[i]; attr; attr = attr->next)
5377       {
5378         FILE *outf;
5379 
5380 #define IS_ATTR_GROUP(X) (!strncmp (attr->name, X, strlen (X)))
5381 	if (IS_ATTR_GROUP ("*internal_dfa_insn_code"))
5382 	  outf = dfa_file;
5383 	else if (IS_ATTR_GROUP ("*insn_default_latency"))
5384 	  outf = latency_file;
5385 	else
5386 	  outf = attr_file;
5387 #undef IS_ATTR_GROUP
5388 
5389 	if (! attr->is_special && ! attr->is_const)
5390 	  write_attr_get (outf, attr);
5391       }
5392 
5393   /* Write out delay eligibility information, if DEFINE_DELAY present.
5394      (The function to compute the number of delay slots will be written
5395      below.)  */
5396   write_eligible_delay (attr_file, "delay");
5397   if (have_annul_true)
5398     write_eligible_delay (attr_file, "annul_true");
5399   else
5400     write_dummy_eligible_delay (attr_file, "annul_true");
5401   if (have_annul_false)
5402     write_eligible_delay (attr_file, "annul_false");
5403   else
5404     write_dummy_eligible_delay (attr_file, "annul_false");
5405 
5406   /* Write out constant delay slot info.  */
5407   write_const_num_delay_slots (attr_file);
5408 
5409   write_length_unit_log (attr_file);
5410 
5411   if (fclose (attr_file) != 0)
5412     fatal ("cannot close file %s: %s", attr_file_name, xstrerror (errno));
5413   if (fclose (dfa_file) != 0)
5414     fatal ("cannot close file %s: %s", dfa_file_name, xstrerror (errno));
5415   if (fclose (latency_file) != 0)
5416     fatal ("cannot close file %s: %s", latency_file_name, xstrerror (errno));
5417 
5418   return SUCCESS_EXIT_CODE;
5419 }
5420 
5421