1 /* Support routines for the various generation passes.
2    Copyright (C) 2000-2013 Free Software Foundation, Inc.
3 
4    This file is part of GCC.
5 
6    GCC is free software; you can redistribute it and/or modify it
7    under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3, or (at your option)
9    any later version.
10 
11    GCC is distributed in the hope that it will be useful, but WITHOUT
12    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
14    License for more details.
15 
16    You should have received a copy of the GNU General Public License
17    along with GCC; see the file COPYING3.  If not see
18    <http://www.gnu.org/licenses/>.  */
19 
20 #include "bconfig.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "tm.h"
24 #include "rtl.h"
25 #include "obstack.h"
26 #include "errors.h"
27 #include "hashtab.h"
28 #include "read-md.h"
29 #include "gensupport.h"
30 
31 #define MAX_OPERANDS 40
32 
33 static rtx operand_data[MAX_OPERANDS];
34 static rtx match_operand_entries_in_pattern[MAX_OPERANDS];
35 static char used_operands_numbers[MAX_OPERANDS];
36 
37 
38 /* In case some macros used by files we include need it, define this here.  */
39 int target_flags;
40 
41 int insn_elision = 1;
42 
43 static struct obstack obstack;
44 struct obstack *rtl_obstack = &obstack;
45 
46 /* Counter for patterns that generate code: define_insn, define_expand,
47    define_split, define_peephole, and define_peephole2.  See read_md_rtx().
48    Any define_insn_and_splits are already in separate queues so that the
49    insn and the splitter get a unique number also.  */
50 static int sequence_num;
51 
52 static int predicable_default;
53 static const char *predicable_true;
54 static const char *predicable_false;
55 
56 static const char *subst_true = "yes";
57 static const char *subst_false = "no";
58 
59 static htab_t condition_table;
60 
61 /* We initially queue all patterns, process the define_insn,
62    define_cond_exec and define_subst patterns, then return
63    them one at a time.  */
64 
65 struct queue_elem
66 {
67   rtx data;
68   const char *filename;
69   int lineno;
70   struct queue_elem *next;
71   /* In a DEFINE_INSN that came from a DEFINE_INSN_AND_SPLIT, SPLIT
72      points to the generated DEFINE_SPLIT.  */
73   struct queue_elem *split;
74 };
75 
76 #define MNEMONIC_ATTR_NAME "mnemonic"
77 #define MNEMONIC_HTAB_SIZE 1024
78 
79 static struct queue_elem *define_attr_queue;
80 static struct queue_elem **define_attr_tail = &define_attr_queue;
81 static struct queue_elem *define_pred_queue;
82 static struct queue_elem **define_pred_tail = &define_pred_queue;
83 static struct queue_elem *define_insn_queue;
84 static struct queue_elem **define_insn_tail = &define_insn_queue;
85 static struct queue_elem *define_cond_exec_queue;
86 static struct queue_elem **define_cond_exec_tail = &define_cond_exec_queue;
87 static struct queue_elem *define_subst_queue;
88 static struct queue_elem **define_subst_tail = &define_subst_queue;
89 static struct queue_elem *other_queue;
90 static struct queue_elem **other_tail = &other_queue;
91 static struct queue_elem *define_subst_attr_queue;
92 static struct queue_elem **define_subst_attr_tail = &define_subst_attr_queue;
93 
94 static struct queue_elem *queue_pattern (rtx, struct queue_elem ***,
95 					 const char *, int);
96 
97 static void remove_constraints (rtx);
98 static void process_rtx (rtx, int);
99 
100 static int is_predicable (struct queue_elem *);
101 static void identify_predicable_attribute (void);
102 static int n_alternatives (const char *);
103 static void collect_insn_data (rtx, int *, int *);
104 static rtx alter_predicate_for_insn (rtx, int, int, int);
105 static const char *alter_test_for_insn (struct queue_elem *,
106 					struct queue_elem *);
107 static char *shift_output_template (char *, const char *, int);
108 static const char *alter_output_for_insn (struct queue_elem *,
109 					  struct queue_elem *,
110 					  int, int);
111 static void process_one_cond_exec (struct queue_elem *);
112 static void process_define_cond_exec (void);
113 static void init_predicate_table (void);
114 static void record_insn_name (int, const char *);
115 
116 static bool has_subst_attribute (struct queue_elem *, struct queue_elem *);
117 static bool subst_pattern_match (rtx, rtx, int);
118 static int get_alternatives_number (rtx, int *, int);
119 static const char * alter_output_for_subst_insn (rtx, int);
120 static void alter_attrs_for_subst_insn (struct queue_elem *, int);
121 static void process_substs_on_one_elem (struct queue_elem *,
122 					struct queue_elem *);
123 static rtx subst_dup (rtx, int, int);
124 static void process_define_subst (void);
125 
126 static const char * duplicate_alternatives (const char *, int);
127 static const char * duplicate_each_alternative (const char * str, int n_dup);
128 
129 typedef const char * (*constraints_handler_t) (const char *, int);
130 static rtx alter_constraints (rtx, int, constraints_handler_t);
131 static rtx adjust_operands_numbers (rtx);
132 static rtx replace_duplicating_operands_in_pattern (rtx);
133 
134 /* Make a version of gen_rtx_CONST_INT so that GEN_INT can be used in
135    the gensupport programs.  */
136 
137 rtx
gen_rtx_CONST_INT(enum machine_mode ARG_UNUSED (mode),HOST_WIDE_INT arg)138 gen_rtx_CONST_INT (enum machine_mode ARG_UNUSED (mode),
139 		   HOST_WIDE_INT arg)
140 {
141   rtx rt = rtx_alloc (CONST_INT);
142 
143   XWINT (rt, 0) = arg;
144   return rt;
145 }
146 
147 /* Predicate handling.
148 
149    We construct from the machine description a table mapping each
150    predicate to a list of the rtl codes it can possibly match.  The
151    function 'maybe_both_true' uses it to deduce that there are no
152    expressions that can be matches by certain pairs of tree nodes.
153    Also, if a predicate can match only one code, we can hardwire that
154    code into the node testing the predicate.
155 
156    Some predicates are flagged as special.  validate_pattern will not
157    warn about modeless match_operand expressions if they have a
158    special predicate.  Predicates that allow only constants are also
159    treated as special, for this purpose.
160 
161    validate_pattern will warn about predicates that allow non-lvalues
162    when they appear in destination operands.
163 
164    Calculating the set of rtx codes that can possibly be accepted by a
165    predicate expression EXP requires a three-state logic: any given
166    subexpression may definitively accept a code C (Y), definitively
167    reject a code C (N), or may have an indeterminate effect (I).  N
168    and I is N; Y or I is Y; Y and I, N or I are both I.  Here are full
169    truth tables.
170 
171      a b  a&b  a|b
172      Y Y   Y    Y
173      N Y   N    Y
174      N N   N    N
175      I Y   I    Y
176      I N   N    I
177      I I   I    I
178 
179    We represent Y with 1, N with 0, I with 2.  If any code is left in
180    an I state by the complete expression, we must assume that that
181    code can be accepted.  */
182 
183 #define N 0
184 #define Y 1
185 #define I 2
186 
187 #define TRISTATE_AND(a,b)			\
188   ((a) == I ? ((b) == N ? N : I) :		\
189    (b) == I ? ((a) == N ? N : I) :		\
190    (a) && (b))
191 
192 #define TRISTATE_OR(a,b)			\
193   ((a) == I ? ((b) == Y ? Y : I) :		\
194    (b) == I ? ((a) == Y ? Y : I) :		\
195    (a) || (b))
196 
197 #define TRISTATE_NOT(a)				\
198   ((a) == I ? I : !(a))
199 
200 /* 0 means no warning about that code yet, 1 means warned.  */
201 static char did_you_mean_codes[NUM_RTX_CODE];
202 
203 /* Recursively calculate the set of rtx codes accepted by the
204    predicate expression EXP, writing the result to CODES.  LINENO is
205    the line number on which the directive containing EXP appeared.  */
206 
207 static void
compute_predicate_codes(rtx exp,int lineno,char codes[NUM_RTX_CODE])208 compute_predicate_codes (rtx exp, int lineno, char codes[NUM_RTX_CODE])
209 {
210   char op0_codes[NUM_RTX_CODE];
211   char op1_codes[NUM_RTX_CODE];
212   char op2_codes[NUM_RTX_CODE];
213   int i;
214 
215   switch (GET_CODE (exp))
216     {
217     case AND:
218       compute_predicate_codes (XEXP (exp, 0), lineno, op0_codes);
219       compute_predicate_codes (XEXP (exp, 1), lineno, op1_codes);
220       for (i = 0; i < NUM_RTX_CODE; i++)
221 	codes[i] = TRISTATE_AND (op0_codes[i], op1_codes[i]);
222       break;
223 
224     case IOR:
225       compute_predicate_codes (XEXP (exp, 0), lineno, op0_codes);
226       compute_predicate_codes (XEXP (exp, 1), lineno, op1_codes);
227       for (i = 0; i < NUM_RTX_CODE; i++)
228 	codes[i] = TRISTATE_OR (op0_codes[i], op1_codes[i]);
229       break;
230     case NOT:
231       compute_predicate_codes (XEXP (exp, 0), lineno, op0_codes);
232       for (i = 0; i < NUM_RTX_CODE; i++)
233 	codes[i] = TRISTATE_NOT (op0_codes[i]);
234       break;
235 
236     case IF_THEN_ELSE:
237       /* a ? b : c  accepts the same codes as (a & b) | (!a & c).  */
238       compute_predicate_codes (XEXP (exp, 0), lineno, op0_codes);
239       compute_predicate_codes (XEXP (exp, 1), lineno, op1_codes);
240       compute_predicate_codes (XEXP (exp, 2), lineno, op2_codes);
241       for (i = 0; i < NUM_RTX_CODE; i++)
242 	codes[i] = TRISTATE_OR (TRISTATE_AND (op0_codes[i], op1_codes[i]),
243 				TRISTATE_AND (TRISTATE_NOT (op0_codes[i]),
244 					      op2_codes[i]));
245       break;
246 
247     case MATCH_CODE:
248       /* MATCH_CODE allows a specified list of codes.  However, if it
249 	 does not apply to the top level of the expression, it does not
250 	 constrain the set of codes for the top level.  */
251       if (XSTR (exp, 1)[0] != '\0')
252 	{
253 	  memset (codes, Y, NUM_RTX_CODE);
254 	  break;
255 	}
256 
257       memset (codes, N, NUM_RTX_CODE);
258       {
259 	const char *next_code = XSTR (exp, 0);
260 	const char *code;
261 
262 	if (*next_code == '\0')
263 	  {
264 	    error_with_line (lineno, "empty match_code expression");
265 	    break;
266 	  }
267 
268 	while ((code = scan_comma_elt (&next_code)) != 0)
269 	  {
270 	    size_t n = next_code - code;
271 	    int found_it = 0;
272 
273 	    for (i = 0; i < NUM_RTX_CODE; i++)
274 	      if (!strncmp (code, GET_RTX_NAME (i), n)
275 		  && GET_RTX_NAME (i)[n] == '\0')
276 		{
277 		  codes[i] = Y;
278 		  found_it = 1;
279 		  break;
280 		}
281 	    if (!found_it)
282 	      {
283 		error_with_line (lineno,
284 				 "match_code \"%.*s\" matches nothing",
285 				 (int) n, code);
286 		for (i = 0; i < NUM_RTX_CODE; i++)
287 		  if (!strncasecmp (code, GET_RTX_NAME (i), n)
288 		      && GET_RTX_NAME (i)[n] == '\0'
289 		      && !did_you_mean_codes[i])
290 		    {
291 		      did_you_mean_codes[i] = 1;
292 		      message_with_line (lineno, "(did you mean \"%s\"?)",
293 					 GET_RTX_NAME (i));
294 		    }
295 	      }
296 	  }
297       }
298       break;
299 
300     case MATCH_OPERAND:
301       /* MATCH_OPERAND disallows the set of codes that the named predicate
302 	 disallows, and is indeterminate for the codes that it does allow.  */
303       {
304 	struct pred_data *p = lookup_predicate (XSTR (exp, 1));
305 	if (!p)
306 	  {
307 	    error_with_line (lineno, "reference to unknown predicate '%s'",
308 			     XSTR (exp, 1));
309 	    break;
310 	  }
311 	for (i = 0; i < NUM_RTX_CODE; i++)
312 	  codes[i] = p->codes[i] ? I : N;
313       }
314       break;
315 
316 
317     case MATCH_TEST:
318       /* (match_test WHATEVER) is completely indeterminate.  */
319       memset (codes, I, NUM_RTX_CODE);
320       break;
321 
322     default:
323       error_with_line (lineno,
324 		       "'%s' cannot be used in a define_predicate expression",
325 		       GET_RTX_NAME (GET_CODE (exp)));
326       memset (codes, I, NUM_RTX_CODE);
327       break;
328     }
329 }
330 
331 #undef TRISTATE_OR
332 #undef TRISTATE_AND
333 #undef TRISTATE_NOT
334 
335 /* Return true if NAME is a valid predicate name.  */
336 
337 static bool
valid_predicate_name_p(const char * name)338 valid_predicate_name_p (const char *name)
339 {
340   const char *p;
341 
342   if (!ISALPHA (name[0]) && name[0] != '_')
343     return false;
344   for (p = name + 1; *p; p++)
345     if (!ISALNUM (*p) && *p != '_')
346       return false;
347   return true;
348 }
349 
350 /* Process define_predicate directive DESC, which appears on line number
351    LINENO.  Compute the set of codes that can be matched, and record this
352    as a known predicate.  */
353 
354 static void
process_define_predicate(rtx desc,int lineno)355 process_define_predicate (rtx desc, int lineno)
356 {
357   struct pred_data *pred;
358   char codes[NUM_RTX_CODE];
359   int i;
360 
361   if (!valid_predicate_name_p (XSTR (desc, 0)))
362     {
363       error_with_line (lineno,
364 		       "%s: predicate name must be a valid C function name",
365 		       XSTR (desc, 0));
366       return;
367     }
368 
369   pred = XCNEW (struct pred_data);
370   pred->name = XSTR (desc, 0);
371   pred->exp = XEXP (desc, 1);
372   pred->c_block = XSTR (desc, 2);
373   if (GET_CODE (desc) == DEFINE_SPECIAL_PREDICATE)
374     pred->special = true;
375 
376   compute_predicate_codes (XEXP (desc, 1), lineno, codes);
377 
378   for (i = 0; i < NUM_RTX_CODE; i++)
379     if (codes[i] != N)
380       add_predicate_code (pred, (enum rtx_code) i);
381 
382   add_predicate (pred);
383 }
384 #undef I
385 #undef N
386 #undef Y
387 
388 /* Queue PATTERN on LIST_TAIL.  Return the address of the new queue
389    element.  */
390 
391 static struct queue_elem *
queue_pattern(rtx pattern,struct queue_elem *** list_tail,const char * filename,int lineno)392 queue_pattern (rtx pattern, struct queue_elem ***list_tail,
393 	       const char *filename, int lineno)
394 {
395   struct queue_elem *e = XNEW(struct queue_elem);
396   e->data = pattern;
397   e->filename = filename;
398   e->lineno = lineno;
399   e->next = NULL;
400   e->split = NULL;
401   **list_tail = e;
402   *list_tail = &e->next;
403   return e;
404 }
405 
406 /* Remove element ELEM from QUEUE.  */
407 static void
remove_from_queue(struct queue_elem * elem,struct queue_elem ** queue)408 remove_from_queue (struct queue_elem *elem, struct queue_elem **queue)
409 {
410   struct queue_elem *prev, *e;
411   prev = NULL;
412   for (e = *queue; e ; e = e->next)
413     {
414       if (e == elem)
415 	break;
416       prev = e;
417     }
418   if (e == NULL)
419     return;
420 
421   if (prev)
422     prev->next = elem->next;
423   else
424     *queue = elem->next;
425 }
426 
427 /* Build a define_attr for an binary attribute with name NAME and
428    possible values "yes" and "no", and queue it.  */
429 static void
add_define_attr(const char * name)430 add_define_attr (const char *name)
431 {
432   struct queue_elem *e = XNEW(struct queue_elem);
433   rtx t1 = rtx_alloc (DEFINE_ATTR);
434   XSTR (t1, 0) = name;
435   XSTR (t1, 1) = "no,yes";
436   XEXP (t1, 2) = rtx_alloc (CONST_STRING);
437   XSTR (XEXP (t1, 2), 0) = "yes";
438   e->data = t1;
439   e->filename = "built-in";
440   e->lineno = -1;
441   e->next = define_attr_queue;
442   define_attr_queue = e;
443 
444 }
445 
446 /* Recursively remove constraints from an rtx.  */
447 
448 static void
remove_constraints(rtx part)449 remove_constraints (rtx part)
450 {
451   int i, j;
452   const char *format_ptr;
453 
454   if (part == 0)
455     return;
456 
457   if (GET_CODE (part) == MATCH_OPERAND)
458     XSTR (part, 2) = "";
459   else if (GET_CODE (part) == MATCH_SCRATCH)
460     XSTR (part, 1) = "";
461 
462   format_ptr = GET_RTX_FORMAT (GET_CODE (part));
463 
464   for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
465     switch (*format_ptr++)
466       {
467       case 'e':
468       case 'u':
469 	remove_constraints (XEXP (part, i));
470 	break;
471       case 'E':
472 	if (XVEC (part, i) != NULL)
473 	  for (j = 0; j < XVECLEN (part, i); j++)
474 	    remove_constraints (XVECEXP (part, i, j));
475 	break;
476       }
477 }
478 
479 /* Process a top level rtx in some way, queuing as appropriate.  */
480 
481 static void
process_rtx(rtx desc,int lineno)482 process_rtx (rtx desc, int lineno)
483 {
484   switch (GET_CODE (desc))
485     {
486     case DEFINE_INSN:
487       queue_pattern (desc, &define_insn_tail, read_md_filename, lineno);
488       break;
489 
490     case DEFINE_COND_EXEC:
491       queue_pattern (desc, &define_cond_exec_tail, read_md_filename, lineno);
492       break;
493 
494     case DEFINE_SUBST:
495       queue_pattern (desc, &define_subst_tail, read_md_filename, lineno);
496       break;
497 
498     case DEFINE_SUBST_ATTR:
499       queue_pattern (desc, &define_subst_attr_tail, read_md_filename, lineno);
500       break;
501 
502     case DEFINE_ATTR:
503     case DEFINE_ENUM_ATTR:
504       queue_pattern (desc, &define_attr_tail, read_md_filename, lineno);
505       break;
506 
507     case DEFINE_PREDICATE:
508     case DEFINE_SPECIAL_PREDICATE:
509       process_define_predicate (desc, lineno);
510       /* Fall through.  */
511 
512     case DEFINE_CONSTRAINT:
513     case DEFINE_REGISTER_CONSTRAINT:
514     case DEFINE_MEMORY_CONSTRAINT:
515     case DEFINE_ADDRESS_CONSTRAINT:
516       queue_pattern (desc, &define_pred_tail, read_md_filename, lineno);
517       break;
518 
519     case DEFINE_INSN_AND_SPLIT:
520       {
521 	const char *split_cond;
522 	rtx split;
523 	rtvec attr;
524 	int i;
525 	struct queue_elem *insn_elem;
526 	struct queue_elem *split_elem;
527 
528 	/* Create a split with values from the insn_and_split.  */
529 	split = rtx_alloc (DEFINE_SPLIT);
530 
531 	i = XVECLEN (desc, 1);
532 	XVEC (split, 0) = rtvec_alloc (i);
533 	while (--i >= 0)
534 	  {
535 	    XVECEXP (split, 0, i) = copy_rtx (XVECEXP (desc, 1, i));
536 	    remove_constraints (XVECEXP (split, 0, i));
537 	  }
538 
539 	/* If the split condition starts with "&&", append it to the
540 	   insn condition to create the new split condition.  */
541 	split_cond = XSTR (desc, 4);
542 	if (split_cond[0] == '&' && split_cond[1] == '&')
543 	  {
544 	    copy_md_ptr_loc (split_cond + 2, split_cond);
545 	    split_cond = join_c_conditions (XSTR (desc, 2), split_cond + 2);
546 	  }
547 	XSTR (split, 1) = split_cond;
548 	XVEC (split, 2) = XVEC (desc, 5);
549 	XSTR (split, 3) = XSTR (desc, 6);
550 
551 	/* Fix up the DEFINE_INSN.  */
552 	attr = XVEC (desc, 7);
553 	PUT_CODE (desc, DEFINE_INSN);
554 	XVEC (desc, 4) = attr;
555 
556 	/* Queue them.  */
557 	insn_elem
558 	  = queue_pattern (desc, &define_insn_tail, read_md_filename,
559 			   lineno);
560 	split_elem
561 	  = queue_pattern (split, &other_tail, read_md_filename, lineno);
562 	insn_elem->split = split_elem;
563 	break;
564       }
565 
566     default:
567       queue_pattern (desc, &other_tail, read_md_filename, lineno);
568       break;
569     }
570 }
571 
572 /* Return true if attribute PREDICABLE is true for ELEM, which holds
573    a DEFINE_INSN.  */
574 
575 static int
is_predicable(struct queue_elem * elem)576 is_predicable (struct queue_elem *elem)
577 {
578   rtvec vec = XVEC (elem->data, 4);
579   const char *value;
580   int i;
581 
582   if (! vec)
583     return predicable_default;
584 
585   for (i = GET_NUM_ELEM (vec) - 1; i >= 0; --i)
586     {
587       rtx sub = RTVEC_ELT (vec, i);
588       switch (GET_CODE (sub))
589 	{
590 	case SET_ATTR:
591 	  if (strcmp (XSTR (sub, 0), "predicable") == 0)
592 	    {
593 	      value = XSTR (sub, 1);
594 	      goto found;
595 	    }
596 	  break;
597 
598 	case SET_ATTR_ALTERNATIVE:
599 	  if (strcmp (XSTR (sub, 0), "predicable") == 0)
600 	    {
601 	      error_with_line (elem->lineno,
602 			       "multiple alternatives for `predicable'");
603 	      return 0;
604 	    }
605 	  break;
606 
607 	case SET:
608 	  if (GET_CODE (SET_DEST (sub)) != ATTR
609 	      || strcmp (XSTR (SET_DEST (sub), 0), "predicable") != 0)
610 	    break;
611 	  sub = SET_SRC (sub);
612 	  if (GET_CODE (sub) == CONST_STRING)
613 	    {
614 	      value = XSTR (sub, 0);
615 	      goto found;
616 	    }
617 
618 	  /* ??? It would be possible to handle this if we really tried.
619 	     It's not easy though, and I'm not going to bother until it
620 	     really proves necessary.  */
621 	  error_with_line (elem->lineno,
622 			   "non-constant value for `predicable'");
623 	  return 0;
624 
625 	default:
626 	  gcc_unreachable ();
627 	}
628     }
629 
630   return predicable_default;
631 
632  found:
633   /* Find out which value we're looking at.  Multiple alternatives means at
634      least one is predicable.  */
635   if (strchr (value, ',') != NULL)
636     return 1;
637   if (strcmp (value, predicable_true) == 0)
638     return 1;
639   if (strcmp (value, predicable_false) == 0)
640     return 0;
641 
642   error_with_line (elem->lineno,
643 		   "unknown value `%s' for `predicable' attribute", value);
644   return 0;
645 }
646 
647 /* Find attribute SUBST in ELEM and assign NEW_VALUE to it.  */
648 static void
change_subst_attribute(struct queue_elem * elem,struct queue_elem * subst_elem,const char * new_value)649 change_subst_attribute (struct queue_elem *elem,
650 			struct queue_elem *subst_elem,
651 			const char *new_value)
652 {
653   rtvec attrs_vec = XVEC (elem->data, 4);
654   const char *subst_name = XSTR (subst_elem->data, 0);
655   int i;
656 
657   if (! attrs_vec)
658     return;
659 
660   for (i = GET_NUM_ELEM (attrs_vec) - 1; i >= 0; --i)
661     {
662       rtx cur_attr = RTVEC_ELT (attrs_vec, i);
663       if (GET_CODE (cur_attr) != SET_ATTR)
664 	continue;
665       if (strcmp (XSTR (cur_attr, 0), subst_name) == 0)
666 	{
667 	  XSTR (cur_attr, 1) = new_value;
668 	  return;
669 	}
670     }
671 }
672 
673 /* Return true if ELEM has the attribute with the name of DEFINE_SUBST
674    represented by SUBST_ELEM and this attribute has value SUBST_TRUE.
675    DEFINE_SUBST isn't applied to patterns without such attribute.  In other
676    words, we suppose the default value of the attribute to be 'no' since it is
677    always generated automaticaly in read-rtl.c.  */
678 static bool
has_subst_attribute(struct queue_elem * elem,struct queue_elem * subst_elem)679 has_subst_attribute (struct queue_elem *elem, struct queue_elem *subst_elem)
680 {
681   rtvec attrs_vec = XVEC (elem->data, 4);
682   const char *value, *subst_name = XSTR (subst_elem->data, 0);
683   int i;
684 
685   if (! attrs_vec)
686     return false;
687 
688   for (i = GET_NUM_ELEM (attrs_vec) - 1; i >= 0; --i)
689     {
690       rtx cur_attr = RTVEC_ELT (attrs_vec, i);
691       switch (GET_CODE (cur_attr))
692 	{
693 	case SET_ATTR:
694 	  if (strcmp (XSTR (cur_attr, 0), subst_name) == 0)
695 	    {
696 	      value = XSTR (cur_attr, 1);
697 	      goto found;
698 	    }
699 	  break;
700 
701 	case SET:
702 	  if (GET_CODE (SET_DEST (cur_attr)) != ATTR
703 	      || strcmp (XSTR (SET_DEST (cur_attr), 0), subst_name) != 0)
704 	    break;
705 	  cur_attr = SET_SRC (cur_attr);
706 	  if (GET_CODE (cur_attr) == CONST_STRING)
707 	    {
708 	      value = XSTR (cur_attr, 0);
709 	      goto found;
710 	    }
711 
712 	  /* Only (set_attr "subst" "yes/no") and
713 		  (set (attr "subst" (const_string "yes/no")))
714 	     are currently allowed.  */
715 	  error_with_line (elem->lineno,
716 			   "unsupported value for `%s'", subst_name);
717 	  return false;
718 
719 	case SET_ATTR_ALTERNATIVE:
720 	  error_with_line (elem->lineno,
721 			   "%s: `set_attr_alternative' is unsupported by "
722 			   "`define_subst'",
723 			   XSTR (elem->data, 0));
724 	  return false;
725 
726 
727 	default:
728 	  gcc_unreachable ();
729 	}
730     }
731 
732   return false;
733 
734  found:
735   if (strcmp (value, subst_true) == 0)
736     return true;
737   if (strcmp (value, subst_false) == 0)
738     return false;
739 
740   error_with_line (elem->lineno,
741 		   "unknown value `%s' for `%s' attribute", value, subst_name);
742   return false;
743 }
744 
745 /* Compare RTL-template of original define_insn X to input RTL-template of
746    define_subst PT.  Return 1 if the templates match, 0 otherwise.
747    During the comparison, the routine also fills global_array OPERAND_DATA.  */
748 static bool
subst_pattern_match(rtx x,rtx pt,int lineno)749 subst_pattern_match (rtx x, rtx pt, int lineno)
750 {
751   RTX_CODE code, code_pt;
752   int i, j, len;
753   const char *fmt, *pred_name;
754 
755   code = GET_CODE (x);
756   code_pt = GET_CODE (pt);
757 
758   if (code_pt == MATCH_OPERAND)
759     {
760       /* MATCH_DUP, and MATCH_OP_DUP don't have a specified mode, so we
761 	 always accept them.  */
762       if (GET_MODE (pt) != VOIDmode && GET_MODE (x) != GET_MODE (pt)
763 	  && (code != MATCH_DUP && code != MATCH_OP_DUP))
764 	return false; /* Modes don't match.  */
765 
766       if (code == MATCH_OPERAND)
767 	{
768 	  pred_name = XSTR (pt, 1);
769 	  if (pred_name[0] != 0)
770 	    {
771 	      const struct pred_data *pred_pt = lookup_predicate (pred_name);
772 	      if (!pred_pt || pred_pt != lookup_predicate (XSTR (x, 1)))
773 		return false; /* Predicates don't match.  */
774 	    }
775 	}
776 
777       gcc_assert (XINT (pt, 0) >= 0 && XINT (pt, 0) < MAX_OPERANDS);
778       operand_data[XINT (pt, 0)] = x;
779       return true;
780     }
781 
782   if (code_pt == MATCH_OPERATOR)
783     {
784       int x_vecexp_pos = -1;
785 
786       /* Compare modes.  */
787       if (GET_MODE (pt) != VOIDmode && GET_MODE (x) != GET_MODE (pt))
788 	return false;
789 
790       /* In case X is also match_operator, compare predicates.  */
791       if (code == MATCH_OPERATOR)
792 	{
793 	  pred_name = XSTR (pt, 1);
794 	  if (pred_name[0] != 0)
795 	    {
796 	      const struct pred_data *pred_pt = lookup_predicate (pred_name);
797 	      if (!pred_pt || pred_pt != lookup_predicate (XSTR (x, 1)))
798 		return false;
799 	    }
800 	}
801 
802       /* Compare operands.
803 	 MATCH_OPERATOR in input template could match in original template
804 	 either 1) MATCH_OPERAND, 2) UNSPEC, 3) ordinary operation (like PLUS).
805 	 In the first case operands are at (XVECEXP (x, 2, j)), in the second
806 	 - at (XVECEXP (x, 0, j)), in the last one - (XEXP (x, j)).
807 	 X_VECEXP_POS variable shows, where to look for these operands.  */
808       if (code == UNSPEC
809 	  || code == UNSPEC_VOLATILE)
810 	x_vecexp_pos = 0;
811       else if (code == MATCH_OPERATOR)
812 	x_vecexp_pos = 2;
813       else
814 	x_vecexp_pos = -1;
815 
816       /* MATCH_OPERATOR or UNSPEC case.  */
817       if (x_vecexp_pos >= 0)
818 	{
819 	  /* Compare operands number in X and PT.  */
820 	  if (XVECLEN (x, x_vecexp_pos) != XVECLEN (pt, 2))
821 	    return false;
822 	  for (j = 0; j < XVECLEN (pt, 2); j++)
823 	    if (!subst_pattern_match (XVECEXP (x, x_vecexp_pos, j),
824 				      XVECEXP (pt, 2, j), lineno))
825 	      return false;
826 	}
827 
828       /* Ordinary operator.  */
829       else
830 	{
831 	  /* Compare operands number in X and PT.
832 	     We count operands differently for X and PT since we compare
833 	     an operator (with operands directly in RTX) and MATCH_OPERATOR
834 	     (that has a vector with operands).  */
835 	  if (GET_RTX_LENGTH (code) != XVECLEN (pt, 2))
836 	    return false;
837 	  for (j = 0; j < XVECLEN (pt, 2); j++)
838 	    if (!subst_pattern_match (XEXP (x, j), XVECEXP (pt, 2, j), lineno))
839 	      return false;
840 	}
841 
842       /* Store the operand to OPERAND_DATA array.  */
843       gcc_assert (XINT (pt, 0) >= 0 && XINT (pt, 0) < MAX_OPERANDS);
844       operand_data[XINT (pt, 0)] = x;
845       return true;
846     }
847 
848   if (code_pt == MATCH_PAR_DUP
849       || code_pt == MATCH_DUP
850       || code_pt == MATCH_OP_DUP
851       || code_pt == MATCH_SCRATCH
852       || code_pt == MATCH_PARALLEL)
853     {
854       /* Currently interface for these constructions isn't defined -
855 	 probably they aren't needed in input template of define_subst at all.
856 	 So, for now their usage in define_subst is forbidden.  */
857       error_with_line (lineno, "%s cannot be used in define_subst",
858 		       GET_RTX_NAME (code_pt));
859     }
860 
861   gcc_assert (code != MATCH_PAR_DUP
862       && code_pt != MATCH_DUP
863       && code_pt != MATCH_OP_DUP
864       && code_pt != MATCH_SCRATCH
865       && code_pt != MATCH_PARALLEL
866       && code_pt != MATCH_OPERAND
867       && code_pt != MATCH_OPERATOR);
868   /* If PT is none of the handled above, then we match only expressions with
869      the same code in X.  */
870   if (code != code_pt)
871     return false;
872 
873   fmt = GET_RTX_FORMAT (code_pt);
874   len = GET_RTX_LENGTH (code_pt);
875 
876   for (i = 0; i < len; i++)
877     {
878       if (fmt[i] == '0')
879 	break;
880 
881       switch (fmt[i])
882 	{
883 	case 'i': case 'w': case 's':
884 	  continue;
885 
886 	case 'e': case 'u':
887 	  if (!subst_pattern_match (XEXP (x, i), XEXP (pt, i), lineno))
888 	    return false;
889 	  break;
890 	case 'E':
891 	  {
892 	    if (XVECLEN (x, i) != XVECLEN (pt, i))
893 	      return false;
894 	    for (j = 0; j < XVECLEN (pt, i); j++)
895 	      if (!subst_pattern_match (XVECEXP (x, i, j), XVECEXP (pt, i, j),
896 					lineno))
897 		return false;
898 	    break;
899 	  }
900 	default:
901 	  gcc_unreachable ();
902 	}
903     }
904 
905   return true;
906 }
907 
908 /* Examine the attribute "predicable"; discover its boolean values
909    and its default.  */
910 
911 static void
identify_predicable_attribute(void)912 identify_predicable_attribute (void)
913 {
914   struct queue_elem *elem;
915   char *p_true, *p_false;
916   const char *value;
917 
918   /* Look for the DEFINE_ATTR for `predicable', which must exist.  */
919   for (elem = define_attr_queue; elem ; elem = elem->next)
920     if (strcmp (XSTR (elem->data, 0), "predicable") == 0)
921       goto found;
922 
923   error_with_line (define_cond_exec_queue->lineno,
924 		   "attribute `predicable' not defined");
925   return;
926 
927  found:
928   value = XSTR (elem->data, 1);
929   p_false = xstrdup (value);
930   p_true = strchr (p_false, ',');
931   if (p_true == NULL || strchr (++p_true, ',') != NULL)
932     {
933       error_with_line (elem->lineno, "attribute `predicable' is not a boolean");
934       free (p_false);
935       return;
936     }
937   p_true[-1] = '\0';
938 
939   predicable_true = p_true;
940   predicable_false = p_false;
941 
942   switch (GET_CODE (XEXP (elem->data, 2)))
943     {
944     case CONST_STRING:
945       value = XSTR (XEXP (elem->data, 2), 0);
946       break;
947 
948     case CONST:
949       error_with_line (elem->lineno, "attribute `predicable' cannot be const");
950       free (p_false);
951       return;
952 
953     default:
954       error_with_line (elem->lineno,
955 		       "attribute `predicable' must have a constant default");
956       free (p_false);
957       return;
958     }
959 
960   if (strcmp (value, p_true) == 0)
961     predicable_default = 1;
962   else if (strcmp (value, p_false) == 0)
963     predicable_default = 0;
964   else
965     {
966       error_with_line (elem->lineno,
967 		       "unknown value `%s' for `predicable' attribute", value);
968       free (p_false);
969     }
970 }
971 
972 /* Return the number of alternatives in constraint S.  */
973 
974 static int
n_alternatives(const char * s)975 n_alternatives (const char *s)
976 {
977   int n = 1;
978 
979   if (s)
980     while (*s)
981       n += (*s++ == ',');
982 
983   return n;
984 }
985 
986 /* The routine scans rtl PATTERN, find match_operand in it and counts
987    number of alternatives.  If PATTERN contains several match_operands
988    with different number of alternatives, error is emitted, and the
989    routine returns 0.  If all match_operands in PATTERN have the same
990    number of alternatives, it's stored in N_ALT, and the routine returns 1.
991    Argument LINENO is used in when the error is emitted.  */
992 static int
get_alternatives_number(rtx pattern,int * n_alt,int lineno)993 get_alternatives_number (rtx pattern, int *n_alt, int lineno)
994 {
995   const char *fmt;
996   enum rtx_code code;
997   int i, j, len;
998 
999   if (!n_alt)
1000     return 0;
1001 
1002   code = GET_CODE (pattern);
1003   switch (code)
1004     {
1005     case MATCH_OPERAND:
1006       i = n_alternatives (XSTR (pattern, 2));
1007       /* n_alternatives returns 1 if constraint string is empty -
1008 	 here we fix it up.  */
1009       if (!*(XSTR (pattern, 2)))
1010 	i = 0;
1011       if (*n_alt <= 0)
1012 	*n_alt = i;
1013 
1014       else if (i && i != *n_alt)
1015 	{
1016 	  error_with_line (lineno,
1017 			   "wrong number of alternatives in operand %d",
1018 			   XINT (pattern, 0));
1019 	  return 0;
1020 	}
1021 
1022     default:
1023       break;
1024     }
1025 
1026   fmt = GET_RTX_FORMAT (code);
1027   len = GET_RTX_LENGTH (code);
1028   for (i = 0; i < len; i++)
1029     {
1030       switch (fmt[i])
1031 	{
1032 	case 'e': case 'u':
1033 	  if (!get_alternatives_number (XEXP (pattern, i), n_alt, lineno))
1034 		return 0;
1035 	  break;
1036 
1037 	case 'V':
1038 	  if (XVEC (pattern, i) == NULL)
1039 	    break;
1040 
1041 	case 'E':
1042 	  for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
1043 	    if (!get_alternatives_number (XVECEXP (pattern, i, j),
1044 					  n_alt, lineno))
1045 		return 0;
1046 	  break;
1047 
1048 	case 'i': case 'w': case '0': case 's': case 'S': case 'T':
1049 	  break;
1050 
1051 	default:
1052 	  gcc_unreachable ();
1053 	}
1054     }
1055     return 1;
1056 }
1057 
1058 /* Determine how many alternatives there are in INSN, and how many
1059    operands.  */
1060 
1061 static void
collect_insn_data(rtx pattern,int * palt,int * pmax)1062 collect_insn_data (rtx pattern, int *palt, int *pmax)
1063 {
1064   const char *fmt;
1065   enum rtx_code code;
1066   int i, j, len;
1067 
1068   code = GET_CODE (pattern);
1069   switch (code)
1070     {
1071     case MATCH_OPERAND:
1072       i = n_alternatives (XSTR (pattern, 2));
1073       *palt = (i > *palt ? i : *palt);
1074       /* Fall through.  */
1075 
1076     case MATCH_OPERATOR:
1077     case MATCH_SCRATCH:
1078     case MATCH_PARALLEL:
1079       i = XINT (pattern, 0);
1080       if (i > *pmax)
1081 	*pmax = i;
1082       break;
1083 
1084     default:
1085       break;
1086     }
1087 
1088   fmt = GET_RTX_FORMAT (code);
1089   len = GET_RTX_LENGTH (code);
1090   for (i = 0; i < len; i++)
1091     {
1092       switch (fmt[i])
1093 	{
1094 	case 'e': case 'u':
1095 	  collect_insn_data (XEXP (pattern, i), palt, pmax);
1096 	  break;
1097 
1098 	case 'V':
1099 	  if (XVEC (pattern, i) == NULL)
1100 	    break;
1101 	  /* Fall through.  */
1102 	case 'E':
1103 	  for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
1104 	    collect_insn_data (XVECEXP (pattern, i, j), palt, pmax);
1105 	  break;
1106 
1107 	case 'i': case 'w': case '0': case 's': case 'S': case 'T':
1108 	  break;
1109 
1110 	default:
1111 	  gcc_unreachable ();
1112 	}
1113     }
1114 }
1115 
1116 static rtx
alter_predicate_for_insn(rtx pattern,int alt,int max_op,int lineno)1117 alter_predicate_for_insn (rtx pattern, int alt, int max_op, int lineno)
1118 {
1119   const char *fmt;
1120   enum rtx_code code;
1121   int i, j, len;
1122 
1123   code = GET_CODE (pattern);
1124   switch (code)
1125     {
1126     case MATCH_OPERAND:
1127       {
1128 	const char *c = XSTR (pattern, 2);
1129 
1130 	if (n_alternatives (c) != 1)
1131 	  {
1132 	    error_with_line (lineno, "too many alternatives for operand %d",
1133 			     XINT (pattern, 0));
1134 	    return NULL;
1135 	  }
1136 
1137 	/* Replicate C as needed to fill out ALT alternatives.  */
1138 	if (c && *c && alt > 1)
1139 	  {
1140 	    size_t c_len = strlen (c);
1141 	    size_t len = alt * (c_len + 1);
1142 	    char *new_c = XNEWVEC (char, len);
1143 
1144 	    memcpy (new_c, c, c_len);
1145 	    for (i = 1; i < alt; ++i)
1146 	      {
1147 		new_c[i * (c_len + 1) - 1] = ',';
1148 		memcpy (&new_c[i * (c_len + 1)], c, c_len);
1149 	      }
1150 	    new_c[len - 1] = '\0';
1151 	    XSTR (pattern, 2) = new_c;
1152 	  }
1153       }
1154       /* Fall through.  */
1155 
1156     case MATCH_OPERATOR:
1157     case MATCH_SCRATCH:
1158     case MATCH_PARALLEL:
1159       XINT (pattern, 0) += max_op;
1160       break;
1161 
1162     default:
1163       break;
1164     }
1165 
1166   fmt = GET_RTX_FORMAT (code);
1167   len = GET_RTX_LENGTH (code);
1168   for (i = 0; i < len; i++)
1169     {
1170       rtx r;
1171 
1172       switch (fmt[i])
1173 	{
1174 	case 'e': case 'u':
1175 	  r = alter_predicate_for_insn (XEXP (pattern, i), alt,
1176 					max_op, lineno);
1177 	  if (r == NULL)
1178 	    return r;
1179 	  break;
1180 
1181 	case 'E':
1182 	  for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
1183 	    {
1184 	      r = alter_predicate_for_insn (XVECEXP (pattern, i, j),
1185 					    alt, max_op, lineno);
1186 	      if (r == NULL)
1187 		return r;
1188 	    }
1189 	  break;
1190 
1191 	case 'i': case 'w': case '0': case 's':
1192 	  break;
1193 
1194 	default:
1195 	  gcc_unreachable ();
1196 	}
1197     }
1198 
1199   return pattern;
1200 }
1201 
1202 /* Duplicate constraints in PATTERN.  If pattern is from original
1203    rtl-template, we need to duplicate each alternative - for that we
1204    need to use duplicate_each_alternative () as a functor ALTER.
1205    If pattern is from output-pattern of define_subst, we need to
1206    duplicate constraints in another way - with duplicate_alternatives ().
1207    N_DUP is multiplication factor.  */
1208 static rtx
alter_constraints(rtx pattern,int n_dup,constraints_handler_t alter)1209 alter_constraints (rtx pattern, int n_dup, constraints_handler_t alter)
1210 {
1211   const char *fmt;
1212   enum rtx_code code;
1213   int i, j, len;
1214 
1215   code = GET_CODE (pattern);
1216   switch (code)
1217     {
1218     case MATCH_OPERAND:
1219       XSTR (pattern, 2) = alter (XSTR (pattern, 2), n_dup);
1220       break;
1221 
1222     default:
1223       break;
1224     }
1225 
1226   fmt = GET_RTX_FORMAT (code);
1227   len = GET_RTX_LENGTH (code);
1228   for (i = 0; i < len; i++)
1229     {
1230       rtx r;
1231 
1232       switch (fmt[i])
1233 	{
1234 	case 'e': case 'u':
1235 	  r = alter_constraints (XEXP (pattern, i), n_dup, alter);
1236 	  if (r == NULL)
1237 	    return r;
1238 	  break;
1239 
1240 	case 'E':
1241 	  for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
1242 	    {
1243 	      r = alter_constraints (XVECEXP (pattern, i, j), n_dup, alter);
1244 	      if (r == NULL)
1245 		return r;
1246 	    }
1247 	  break;
1248 
1249 	case 'i': case 'w': case '0': case 's':
1250 	  break;
1251 
1252 	default:
1253 	  break;
1254 	}
1255     }
1256 
1257   return pattern;
1258 }
1259 
1260 static const char *
alter_test_for_insn(struct queue_elem * ce_elem,struct queue_elem * insn_elem)1261 alter_test_for_insn (struct queue_elem *ce_elem,
1262 		     struct queue_elem *insn_elem)
1263 {
1264   return join_c_conditions (XSTR (ce_elem->data, 1),
1265 			    XSTR (insn_elem->data, 2));
1266 }
1267 
1268 /* Modify VAL, which is an attribute expression for the "enabled" attribute,
1269    to take "ce_enabled" into account.  Return the new expression.  */
1270 static rtx
modify_attr_enabled_ce(rtx val)1271 modify_attr_enabled_ce (rtx val)
1272 {
1273   rtx eq_attr, str;
1274   rtx ite;
1275   eq_attr = rtx_alloc (EQ_ATTR);
1276   ite = rtx_alloc (IF_THEN_ELSE);
1277   str = rtx_alloc (CONST_STRING);
1278 
1279   XSTR (eq_attr, 0) = "ce_enabled";
1280   XSTR (eq_attr, 1) = "yes";
1281   XSTR (str, 0) = "no";
1282   XEXP (ite, 0) = eq_attr;
1283   XEXP (ite, 1) = val;
1284   XEXP (ite, 2) = str;
1285 
1286   return ite;
1287 }
1288 
1289 /* Alter the attribute vector of INSN, which is a COND_EXEC variant created
1290    from a define_insn pattern.  We must modify the "predicable" attribute
1291    to be named "ce_enabled", and also change any "enabled" attribute that's
1292    present so that it takes ce_enabled into account.
1293    We rely on the fact that INSN was created with copy_rtx, and modify data
1294    in-place.  */
1295 
1296 static void
alter_attrs_for_insn(rtx insn)1297 alter_attrs_for_insn (rtx insn)
1298 {
1299   static bool global_changes_made = false;
1300   rtvec vec = XVEC (insn, 4);
1301   rtvec new_vec;
1302   rtx val, set;
1303   int num_elem;
1304   int predicable_idx = -1;
1305   int enabled_idx = -1;
1306   int i;
1307 
1308   if (! vec)
1309     return;
1310 
1311   num_elem = GET_NUM_ELEM (vec);
1312   for (i = num_elem - 1; i >= 0; --i)
1313     {
1314       rtx sub = RTVEC_ELT (vec, i);
1315       switch (GET_CODE (sub))
1316 	{
1317 	case SET_ATTR:
1318 	  if (strcmp (XSTR (sub, 0), "predicable") == 0)
1319 	    {
1320 	      predicable_idx = i;
1321 	      XSTR (sub, 0) = "ce_enabled";
1322 	    }
1323 	  else if (strcmp (XSTR (sub, 0), "enabled") == 0)
1324 	    {
1325 	      enabled_idx = i;
1326 	      XSTR (sub, 0) = "nonce_enabled";
1327 	    }
1328 	  break;
1329 
1330 	case SET_ATTR_ALTERNATIVE:
1331 	  if (strcmp (XSTR (sub, 0), "predicable") == 0)
1332 	    /* We already give an error elsewhere.  */
1333 	    return;
1334 	  else if (strcmp (XSTR (sub, 0), "enabled") == 0)
1335 	    {
1336 	      enabled_idx = i;
1337 	      XSTR (sub, 0) = "nonce_enabled";
1338 	    }
1339 	  break;
1340 
1341 	case SET:
1342 	  if (GET_CODE (SET_DEST (sub)) != ATTR)
1343 	    break;
1344 	  if (strcmp (XSTR (SET_DEST (sub), 0), "predicable") == 0)
1345 	    {
1346 	      sub = SET_SRC (sub);
1347 	      if (GET_CODE (sub) == CONST_STRING)
1348 		{
1349 		  predicable_idx = i;
1350 		  XSTR (sub, 0) = "ce_enabled";
1351 		}
1352 	      else
1353 		/* We already give an error elsewhere.  */
1354 		return;
1355 	      break;
1356 	    }
1357 	  if (strcmp (XSTR (SET_DEST (sub), 0), "enabled") == 0)
1358 	    {
1359 	      enabled_idx = i;
1360 	      XSTR (SET_DEST (sub), 0) = "nonce_enabled";
1361 	    }
1362 	  break;
1363 
1364 	default:
1365 	  gcc_unreachable ();
1366 	}
1367     }
1368   if (predicable_idx == -1)
1369     return;
1370 
1371   if (!global_changes_made)
1372     {
1373       struct queue_elem *elem;
1374 
1375       global_changes_made = true;
1376       add_define_attr ("ce_enabled");
1377       add_define_attr ("nonce_enabled");
1378 
1379       for (elem = define_attr_queue; elem ; elem = elem->next)
1380 	if (strcmp (XSTR (elem->data, 0), "enabled") == 0)
1381 	  {
1382 	    XEXP (elem->data, 2)
1383 	      = modify_attr_enabled_ce (XEXP (elem->data, 2));
1384 	  }
1385     }
1386   if (enabled_idx == -1)
1387     return;
1388 
1389   new_vec = rtvec_alloc (num_elem + 1);
1390   for (i = 0; i < num_elem; i++)
1391     RTVEC_ELT (new_vec, i) = RTVEC_ELT (vec, i);
1392   val = rtx_alloc (IF_THEN_ELSE);
1393   XEXP (val, 0) = rtx_alloc (EQ_ATTR);
1394   XEXP (val, 1) = rtx_alloc (CONST_STRING);
1395   XEXP (val, 2) = rtx_alloc (CONST_STRING);
1396   XSTR (XEXP (val, 0), 0) = "nonce_enabled";
1397   XSTR (XEXP (val, 0), 1) = "yes";
1398   XSTR (XEXP (val, 1), 0) = "yes";
1399   XSTR (XEXP (val, 2), 0) = "no";
1400   set = rtx_alloc (SET);
1401   SET_DEST (set) = rtx_alloc (ATTR);
1402   XSTR (SET_DEST (set), 0) = "enabled";
1403   SET_SRC (set) = modify_attr_enabled_ce (val);
1404   RTVEC_ELT (new_vec, i) = set;
1405   XVEC (insn, 4) = new_vec;
1406 }
1407 
1408 /* As number of constraints is changed after define_subst, we need to
1409    process attributes as well - we need to duplicate them the same way
1410    that we duplicated constraints in original pattern
1411    ELEM is a queue element, containing our rtl-template,
1412    N_DUP - multiplication factor.  */
1413 static void
alter_attrs_for_subst_insn(struct queue_elem * elem,int n_dup)1414 alter_attrs_for_subst_insn (struct queue_elem * elem, int n_dup)
1415 {
1416   rtvec vec = XVEC (elem->data, 4);
1417   int num_elem;
1418   int i;
1419 
1420   if (n_dup < 2 || ! vec)
1421     return;
1422 
1423   num_elem = GET_NUM_ELEM (vec);
1424   for (i = num_elem - 1; i >= 0; --i)
1425     {
1426       rtx sub = RTVEC_ELT (vec, i);
1427       switch (GET_CODE (sub))
1428 	{
1429 	case SET_ATTR:
1430 	  if (strchr (XSTR (sub, 1), ',') != NULL)
1431 	    XSTR (sub, 1) = duplicate_alternatives (XSTR (sub, 1), n_dup);
1432 	    break;
1433 
1434 	case SET_ATTR_ALTERNATIVE:
1435 	case SET:
1436 	  error_with_line (elem->lineno,
1437 			   "%s: `define_subst' does not support attributes "
1438 			   "assigned by `set' and `set_attr_alternative'",
1439 			   XSTR (elem->data, 0));
1440 	  return;
1441 
1442 	default:
1443 	  gcc_unreachable ();
1444 	}
1445     }
1446 }
1447 
1448 /* Adjust all of the operand numbers in SRC to match the shift they'll
1449    get from an operand displacement of DISP.  Return a pointer after the
1450    adjusted string.  */
1451 
1452 static char *
shift_output_template(char * dest,const char * src,int disp)1453 shift_output_template (char *dest, const char *src, int disp)
1454 {
1455   while (*src)
1456     {
1457       char c = *src++;
1458       *dest++ = c;
1459       if (c == '%')
1460 	{
1461 	  c = *src++;
1462 	  if (ISDIGIT ((unsigned char) c))
1463 	    c += disp;
1464 	  else if (ISALPHA (c))
1465 	    {
1466 	      *dest++ = c;
1467 	      c = *src++ + disp;
1468 	    }
1469 	  *dest++ = c;
1470 	}
1471     }
1472 
1473   return dest;
1474 }
1475 
1476 static const char *
alter_output_for_insn(struct queue_elem * ce_elem,struct queue_elem * insn_elem,int alt,int max_op)1477 alter_output_for_insn (struct queue_elem *ce_elem,
1478 		       struct queue_elem *insn_elem,
1479 		       int alt, int max_op)
1480 {
1481   const char *ce_out, *insn_out;
1482   char *result, *p;
1483   size_t len, ce_len, insn_len;
1484 
1485   /* ??? Could coordinate with genoutput to not duplicate code here.  */
1486 
1487   ce_out = XSTR (ce_elem->data, 2);
1488   insn_out = XTMPL (insn_elem->data, 3);
1489   if (!ce_out || *ce_out == '\0')
1490     return insn_out;
1491 
1492   ce_len = strlen (ce_out);
1493   insn_len = strlen (insn_out);
1494 
1495   if (*insn_out == '*')
1496     /* You must take care of the predicate yourself.  */
1497     return insn_out;
1498 
1499   if (*insn_out == '@')
1500     {
1501       len = (ce_len + 1) * alt + insn_len + 1;
1502       p = result = XNEWVEC (char, len);
1503 
1504       do
1505 	{
1506 	  do
1507 	    *p++ = *insn_out++;
1508 	  while (ISSPACE ((unsigned char) *insn_out));
1509 
1510 	  if (*insn_out != '#')
1511 	    {
1512 	      p = shift_output_template (p, ce_out, max_op);
1513 	      *p++ = ' ';
1514 	    }
1515 
1516 	  do
1517 	    *p++ = *insn_out++;
1518 	  while (*insn_out && *insn_out != '\n');
1519 	}
1520       while (*insn_out);
1521       *p = '\0';
1522     }
1523   else
1524     {
1525       len = ce_len + 1 + insn_len + 1;
1526       result = XNEWVEC (char, len);
1527 
1528       p = shift_output_template (result, ce_out, max_op);
1529       *p++ = ' ';
1530       memcpy (p, insn_out, insn_len + 1);
1531     }
1532 
1533   return result;
1534 }
1535 
1536 /* From string STR "a,b,c" produce "a,b,c,a,b,c,a,b,c", i.e. original
1537    string, duplicated N_DUP times.  */
1538 
1539 static const char *
duplicate_alternatives(const char * str,int n_dup)1540 duplicate_alternatives (const char * str, int n_dup)
1541 {
1542   int i, len, new_len;
1543   char *result, *sp;
1544   const char *cp;
1545 
1546   if (n_dup < 2)
1547     return str;
1548 
1549   while (ISSPACE (*str))
1550     str++;
1551 
1552   if (*str == '\0')
1553     return str;
1554 
1555   cp = str;
1556   len = strlen (str);
1557   new_len = (len + 1) * n_dup;
1558 
1559   sp = result = XNEWVEC (char, new_len);
1560 
1561   /* Global modifier characters mustn't be duplicated: skip if found.  */
1562   if (*cp == '=' || *cp == '+' || *cp == '%')
1563     {
1564       *sp++ = *cp++;
1565       len--;
1566     }
1567 
1568   /* Copy original constraints N_DUP times.  */
1569   for (i = 0; i < n_dup; i++, sp += len+1)
1570     {
1571       memcpy (sp, cp, len);
1572       *(sp+len) = (i == n_dup - 1) ? '\0' : ',';
1573     }
1574 
1575   return result;
1576 }
1577 
1578 /* From string STR "a,b,c" produce "a,a,a,b,b,b,c,c,c", i.e. string where
1579    each alternative from the original string is duplicated N_DUP times.  */
1580 static const char *
duplicate_each_alternative(const char * str,int n_dup)1581 duplicate_each_alternative (const char * str, int n_dup)
1582 {
1583   int i, len, new_len;
1584   char *result, *sp, *ep, *cp;
1585 
1586   if (n_dup < 2)
1587     return str;
1588 
1589   while (ISSPACE (*str))
1590     str++;
1591 
1592   if (*str == '\0')
1593     return str;
1594 
1595   cp = xstrdup (str);
1596 
1597   new_len = (strlen (cp) + 1) * n_dup;
1598 
1599   sp = result = XNEWVEC (char, new_len);
1600 
1601   /* Global modifier characters mustn't be duplicated: skip if found.  */
1602   if (*cp == '=' || *cp == '+' || *cp == '%')
1603       *sp++ = *cp++;
1604 
1605   do
1606     {
1607       if ((ep = strchr (cp, ',')) != NULL)
1608 	*ep++ = '\0';
1609       len = strlen (cp);
1610 
1611       /* Copy a constraint N_DUP times.  */
1612       for (i = 0; i < n_dup; i++, sp += len + 1)
1613 	{
1614 	  memcpy (sp, cp, len);
1615 	  *(sp+len) = (ep == NULL && i == n_dup - 1) ? '\0' : ',';
1616 	}
1617 
1618       cp = ep;
1619     }
1620   while (cp != NULL);
1621 
1622   return result;
1623 }
1624 
1625 /* Alter the output of INSN whose pattern was modified by
1626    DEFINE_SUBST.  We must replicate output strings according
1627    to the new number of alternatives ALT in substituted pattern.
1628    If ALT equals 1, output has one alternative or defined by C
1629    code, then output is returned without any changes.  */
1630 
1631 static const char *
alter_output_for_subst_insn(rtx insn,int alt)1632 alter_output_for_subst_insn (rtx insn, int alt)
1633 {
1634   const char *insn_out, *sp ;
1635   char *old_out, *new_out, *cp;
1636   int i, j, new_len;
1637 
1638   insn_out = XTMPL (insn, 3);
1639 
1640   if (alt < 2 || *insn_out == '*' || *insn_out != '@')
1641     return insn_out;
1642 
1643   old_out = XNEWVEC (char, strlen (insn_out)),
1644   sp = insn_out;
1645 
1646   while (ISSPACE (*sp) || *sp == '@')
1647     sp++;
1648 
1649   for (i = 0; *sp;)
1650     old_out[i++] = *sp++;
1651 
1652   new_len = alt * (i + 1) + 1;
1653 
1654   new_out = XNEWVEC (char, new_len);
1655   new_out[0] = '@';
1656 
1657   for (j = 0, cp = new_out + 1; j < alt; j++, cp += i + 1)
1658     {
1659       memcpy (cp, old_out, i);
1660       *(cp+i) = (j == alt - 1) ? '\0' : '\n';
1661     }
1662 
1663   return new_out;
1664 }
1665 
1666 /* Replicate insns as appropriate for the given DEFINE_COND_EXEC.  */
1667 
1668 static void
process_one_cond_exec(struct queue_elem * ce_elem)1669 process_one_cond_exec (struct queue_elem *ce_elem)
1670 {
1671   struct queue_elem *insn_elem;
1672   for (insn_elem = define_insn_queue; insn_elem ; insn_elem = insn_elem->next)
1673     {
1674       int alternatives, max_operand;
1675       rtx pred, insn, pattern, split;
1676       char *new_name;
1677       int i;
1678 
1679       if (! is_predicable (insn_elem))
1680 	continue;
1681 
1682       alternatives = 1;
1683       max_operand = -1;
1684       collect_insn_data (insn_elem->data, &alternatives, &max_operand);
1685       max_operand += 1;
1686 
1687       if (XVECLEN (ce_elem->data, 0) != 1)
1688 	{
1689 	  error_with_line (ce_elem->lineno, "too many patterns in predicate");
1690 	  return;
1691 	}
1692 
1693       pred = copy_rtx (XVECEXP (ce_elem->data, 0, 0));
1694       pred = alter_predicate_for_insn (pred, alternatives, max_operand,
1695 				       ce_elem->lineno);
1696       if (pred == NULL)
1697 	return;
1698 
1699       /* Construct a new pattern for the new insn.  */
1700       insn = copy_rtx (insn_elem->data);
1701       new_name = XNEWVAR (char, strlen XSTR (insn_elem->data, 0) + 4);
1702       sprintf (new_name, "*p %s", XSTR (insn_elem->data, 0));
1703       XSTR (insn, 0) = new_name;
1704       pattern = rtx_alloc (COND_EXEC);
1705       XEXP (pattern, 0) = pred;
1706       if (XVECLEN (insn, 1) == 1)
1707 	{
1708 	  XEXP (pattern, 1) = XVECEXP (insn, 1, 0);
1709 	  XVECEXP (insn, 1, 0) = pattern;
1710 	  PUT_NUM_ELEM (XVEC (insn, 1), 1);
1711 	}
1712       else
1713 	{
1714 	  XEXP (pattern, 1) = rtx_alloc (PARALLEL);
1715 	  XVEC (XEXP (pattern, 1), 0) = XVEC (insn, 1);
1716 	  XVEC (insn, 1) = rtvec_alloc (1);
1717 	  XVECEXP (insn, 1, 0) = pattern;
1718 	}
1719 
1720       XSTR (insn, 2) = alter_test_for_insn (ce_elem, insn_elem);
1721       XTMPL (insn, 3) = alter_output_for_insn (ce_elem, insn_elem,
1722 					      alternatives, max_operand);
1723       alter_attrs_for_insn (insn);
1724 
1725       /* Put the new pattern on the `other' list so that it
1726 	 (a) is not reprocessed by other define_cond_exec patterns
1727 	 (b) appears after all normal define_insn patterns.
1728 
1729 	 ??? B is debatable.  If one has normal insns that match
1730 	 cond_exec patterns, they will be preferred over these
1731 	 generated patterns.  Whether this matters in practice, or if
1732 	 it's a good thing, or whether we should thread these new
1733 	 patterns into the define_insn chain just after their generator
1734 	 is something we'll have to experiment with.  */
1735 
1736       queue_pattern (insn, &other_tail, insn_elem->filename,
1737 		     insn_elem->lineno);
1738 
1739       if (!insn_elem->split)
1740 	continue;
1741 
1742       /* If the original insn came from a define_insn_and_split,
1743 	 generate a new split to handle the predicated insn.  */
1744       split = copy_rtx (insn_elem->split->data);
1745       /* Predicate the pattern matched by the split.  */
1746       pattern = rtx_alloc (COND_EXEC);
1747       XEXP (pattern, 0) = pred;
1748       if (XVECLEN (split, 0) == 1)
1749 	{
1750 	  XEXP (pattern, 1) = XVECEXP (split, 0, 0);
1751 	  XVECEXP (split, 0, 0) = pattern;
1752 	  PUT_NUM_ELEM (XVEC (split, 0), 1);
1753 	}
1754       else
1755 	{
1756 	  XEXP (pattern, 1) = rtx_alloc (PARALLEL);
1757 	  XVEC (XEXP (pattern, 1), 0) = XVEC (split, 0);
1758 	  XVEC (split, 0) = rtvec_alloc (1);
1759 	  XVECEXP (split, 0, 0) = pattern;
1760 	}
1761       /* Predicate all of the insns generated by the split.  */
1762       for (i = 0; i < XVECLEN (split, 2); i++)
1763 	{
1764 	  pattern = rtx_alloc (COND_EXEC);
1765 	  XEXP (pattern, 0) = pred;
1766 	  XEXP (pattern, 1) = XVECEXP (split, 2, i);
1767 	  XVECEXP (split, 2, i) = pattern;
1768 	}
1769       /* Add the new split to the queue.  */
1770       queue_pattern (split, &other_tail, read_md_filename,
1771 		     insn_elem->split->lineno);
1772     }
1773 }
1774 
1775 /* Try to apply define_substs to the given ELEM.
1776    Only define_substs, specified via attributes would be applied.
1777    If attribute, requiring define_subst, is set, but no define_subst
1778    was applied, ELEM would be deleted.  */
1779 
1780 static void
process_substs_on_one_elem(struct queue_elem * elem,struct queue_elem * queue)1781 process_substs_on_one_elem (struct queue_elem *elem,
1782 			    struct queue_elem *queue)
1783 {
1784   struct queue_elem *subst_elem;
1785   int i, j, patterns_match;
1786 
1787   for (subst_elem = define_subst_queue;
1788        subst_elem; subst_elem = subst_elem->next)
1789     {
1790       int alternatives, alternatives_subst;
1791       rtx subst_pattern;
1792       rtvec subst_pattern_vec;
1793 
1794       if (!has_subst_attribute (elem, subst_elem))
1795 	continue;
1796 
1797       /* Compare original rtl-pattern from define_insn with input
1798 	 pattern from define_subst.
1799 	 Also, check if numbers of alternatives are the same in all
1800 	 match_operands.  */
1801       if (XVECLEN (elem->data, 1) != XVECLEN (subst_elem->data, 1))
1802 	continue;
1803       patterns_match = 1;
1804       alternatives = -1;
1805       alternatives_subst = -1;
1806       for (j = 0; j < XVECLEN (elem->data, 1); j++)
1807 	{
1808 	  if (!subst_pattern_match (XVECEXP (elem->data, 1, j),
1809 				    XVECEXP (subst_elem->data, 1, j),
1810 				    subst_elem->lineno))
1811 	    {
1812 	      patterns_match = 0;
1813 	      break;
1814 	    }
1815 
1816 	  if (!get_alternatives_number (XVECEXP (elem->data, 1, j),
1817 					&alternatives, subst_elem->lineno))
1818 	    {
1819 	      patterns_match = 0;
1820 	      break;
1821 	    }
1822 	}
1823 
1824       /* Check if numbers of alternatives are the same in all
1825 	 match_operands in output template of define_subst.  */
1826       for (j = 0; j < XVECLEN (subst_elem->data, 3); j++)
1827 	{
1828 	  if (!get_alternatives_number (XVECEXP (subst_elem->data, 3, j),
1829 					&alternatives_subst,
1830 					subst_elem->lineno))
1831 	    {
1832 	      patterns_match = 0;
1833 	      break;
1834 	    }
1835 	}
1836 
1837       if (!patterns_match)
1838 	continue;
1839 
1840       /* Clear array in which we save occupied indexes of operands.  */
1841       memset (used_operands_numbers, 0, sizeof (used_operands_numbers));
1842 
1843       /* Create a pattern, based on the output one from define_subst.  */
1844       subst_pattern_vec = rtvec_alloc (XVECLEN (subst_elem->data, 3));
1845       for (j = 0; j < XVECLEN (subst_elem->data, 3); j++)
1846 	{
1847 	  subst_pattern = copy_rtx (XVECEXP (subst_elem->data, 3, j));
1848 
1849 	  /* Duplicate constraints in substitute-pattern.  */
1850 	  subst_pattern = alter_constraints (subst_pattern, alternatives,
1851 					     duplicate_each_alternative);
1852 
1853 	  subst_pattern = adjust_operands_numbers (subst_pattern);
1854 
1855 	  /* Substitute match_dup and match_op_dup in the new pattern and
1856 	     duplicate constraints.  */
1857 	  subst_pattern = subst_dup (subst_pattern, alternatives,
1858 				     alternatives_subst);
1859 
1860 	  replace_duplicating_operands_in_pattern (subst_pattern);
1861 
1862 	  /* We don't need any constraints in DEFINE_EXPAND.  */
1863 	  if (GET_CODE (elem->data) == DEFINE_EXPAND)
1864 	    remove_constraints (subst_pattern);
1865 
1866 	  RTVEC_ELT (subst_pattern_vec, j) = subst_pattern;
1867 	}
1868       XVEC (elem->data, 1) = subst_pattern_vec;
1869 
1870       for (i = 0; i < MAX_OPERANDS; i++)
1871 	  match_operand_entries_in_pattern[i] = NULL;
1872 
1873       if (GET_CODE (elem->data) == DEFINE_INSN)
1874 	{
1875 	  XTMPL (elem->data, 3) =
1876 	    alter_output_for_subst_insn (elem->data, alternatives_subst);
1877 	  alter_attrs_for_subst_insn (elem, alternatives_subst);
1878 	}
1879 
1880       /* Recalculate condition, joining conditions from original and
1881 	 DEFINE_SUBST input patterns.  */
1882       XSTR (elem->data, 2) = join_c_conditions (XSTR (subst_elem->data, 2),
1883 						XSTR (elem->data, 2));
1884       /* Mark that subst was applied by changing attribute from "yes"
1885 	 to "no".  */
1886       change_subst_attribute (elem, subst_elem, subst_false);
1887     }
1888 
1889   /* If ELEM contains a subst attribute with value "yes", then we
1890      expected that a subst would be applied, but it wasn't - so,
1891      we need to remove that elementto avoid duplicating.  */
1892   for (subst_elem = define_subst_queue;
1893        subst_elem; subst_elem = subst_elem->next)
1894     {
1895       if (has_subst_attribute (elem, subst_elem))
1896 	{
1897 	  remove_from_queue (elem, &queue);
1898 	  return;
1899 	}
1900     }
1901 }
1902 
1903 /* This is a subroutine of mark_operands_used_in_match_dup.
1904    This routine is marks all MATCH_OPERANDs inside PATTERN as occupied.  */
1905 static void
mark_operands_from_match_dup(rtx pattern)1906 mark_operands_from_match_dup (rtx pattern)
1907 {
1908   const char *fmt;
1909   int i, j, len, opno;
1910 
1911   if (GET_CODE (pattern) == MATCH_OPERAND
1912       || GET_CODE (pattern) == MATCH_OPERATOR
1913       || GET_CODE (pattern) == MATCH_PARALLEL)
1914     {
1915       opno = XINT (pattern, 0);
1916       gcc_assert (opno >= 0 && opno < MAX_OPERANDS);
1917       used_operands_numbers [opno] = 1;
1918     }
1919   fmt = GET_RTX_FORMAT (GET_CODE (pattern));
1920   len = GET_RTX_LENGTH (GET_CODE (pattern));
1921   for (i = 0; i < len; i++)
1922     {
1923       switch (fmt[i])
1924 	{
1925 	case 'e': case 'u':
1926 	  mark_operands_from_match_dup (XEXP (pattern, i));
1927 	  break;
1928 	case 'E':
1929 	  for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
1930 	    mark_operands_from_match_dup (XVECEXP (pattern, i, j));
1931 	  break;
1932 	}
1933     }
1934 }
1935 
1936 /* This is a subroutine of adjust_operands_numbers.
1937    It goes through all expressions in PATTERN and when MATCH_DUP is
1938    met, all MATCH_OPERANDs inside it is marked as occupied.  The
1939    process of marking is done by routin mark_operands_from_match_dup.  */
1940 static void
mark_operands_used_in_match_dup(rtx pattern)1941 mark_operands_used_in_match_dup (rtx pattern)
1942 {
1943   const char *fmt;
1944   int i, j, len, opno;
1945 
1946   if (GET_CODE (pattern) == MATCH_DUP)
1947     {
1948       opno = XINT (pattern, 0);
1949       gcc_assert (opno >= 0 && opno < MAX_OPERANDS);
1950       mark_operands_from_match_dup (operand_data[opno]);
1951       return;
1952     }
1953   fmt = GET_RTX_FORMAT (GET_CODE (pattern));
1954   len = GET_RTX_LENGTH (GET_CODE (pattern));
1955   for (i = 0; i < len; i++)
1956     {
1957       switch (fmt[i])
1958 	{
1959 	case 'e': case 'u':
1960 	  mark_operands_used_in_match_dup (XEXP (pattern, i));
1961 	  break;
1962 	case 'E':
1963 	  for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
1964 	    mark_operands_used_in_match_dup (XVECEXP (pattern, i, j));
1965 	  break;
1966 	}
1967     }
1968 }
1969 
1970 /* This is subroutine of renumerate_operands_in_pattern.
1971    It finds first not-occupied operand-index.  */
1972 static int
find_first_unused_number_of_operand()1973 find_first_unused_number_of_operand ()
1974 {
1975   int i;
1976   for (i = 0; i < MAX_OPERANDS; i++)
1977     if (!used_operands_numbers[i])
1978       return i;
1979   return MAX_OPERANDS;
1980 }
1981 
1982 /* This is subroutine of adjust_operands_numbers.
1983    It visits all expressions in PATTERN and assigns not-occupied
1984    operand indexes to MATCH_OPERANDs and MATCH_OPERATORs of this
1985    PATTERN.  */
1986 static void
renumerate_operands_in_pattern(rtx pattern)1987 renumerate_operands_in_pattern (rtx pattern)
1988 {
1989   const char *fmt;
1990   enum rtx_code code;
1991   int i, j, len, new_opno;
1992   code = GET_CODE (pattern);
1993 
1994   if (code == MATCH_OPERAND
1995       || code == MATCH_OPERATOR)
1996     {
1997       new_opno = find_first_unused_number_of_operand ();
1998       gcc_assert (new_opno >= 0 && new_opno < MAX_OPERANDS);
1999       XINT (pattern, 0) = new_opno;
2000       used_operands_numbers [new_opno] = 1;
2001     }
2002 
2003   fmt = GET_RTX_FORMAT (GET_CODE (pattern));
2004   len = GET_RTX_LENGTH (GET_CODE (pattern));
2005   for (i = 0; i < len; i++)
2006     {
2007       switch (fmt[i])
2008 	{
2009 	case 'e': case 'u':
2010 	  renumerate_operands_in_pattern (XEXP (pattern, i));
2011 	  break;
2012 	case 'E':
2013 	  for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
2014 	    renumerate_operands_in_pattern (XVECEXP (pattern, i, j));
2015 	  break;
2016 	}
2017     }
2018 }
2019 
2020 /* If output pattern of define_subst contains MATCH_DUP, then this
2021    expression would be replaced with the pattern, matched with
2022    MATCH_OPERAND from input pattern.  This pattern could contain any
2023    number of MATCH_OPERANDs, MATCH_OPERATORs etc., so it's possible
2024    that a MATCH_OPERAND from output_pattern (if any) would have the
2025    same number, as MATCH_OPERAND from copied pattern.  To avoid such
2026    indexes overlapping, we assign new indexes to MATCH_OPERANDs,
2027    laying in the output pattern outside of MATCH_DUPs.  */
2028 static rtx
adjust_operands_numbers(rtx pattern)2029 adjust_operands_numbers (rtx pattern)
2030 {
2031   mark_operands_used_in_match_dup (pattern);
2032 
2033   renumerate_operands_in_pattern (pattern);
2034 
2035   return pattern;
2036 }
2037 
2038 /* Generate RTL expression
2039    (match_dup OPNO)
2040    */
2041 static rtx
generate_match_dup(int opno)2042 generate_match_dup (int opno)
2043 {
2044   rtx return_rtx = rtx_alloc (MATCH_DUP);
2045   PUT_CODE (return_rtx, MATCH_DUP);
2046   XINT (return_rtx, 0) = opno;
2047   return return_rtx;
2048 }
2049 
2050 /* This routine checks all match_operands in PATTERN and if some of
2051    have the same index, it replaces all of them except the first one  to
2052    match_dup.
2053    Usually, match_operands with the same indexes are forbidden, but
2054    after define_subst copy an RTL-expression from original template,
2055    indexes of existed and just-copied match_operands could coincide.
2056    To fix it, we replace one of them with match_dup.  */
2057 static rtx
replace_duplicating_operands_in_pattern(rtx pattern)2058 replace_duplicating_operands_in_pattern (rtx pattern)
2059 {
2060   const char *fmt;
2061   int i, j, len, opno;
2062   rtx mdup;
2063 
2064   if (GET_CODE (pattern) == MATCH_OPERAND)
2065     {
2066       opno = XINT (pattern, 0);
2067       gcc_assert (opno >= 0 && opno < MAX_OPERANDS);
2068       if (match_operand_entries_in_pattern[opno] == NULL)
2069 	{
2070 	  match_operand_entries_in_pattern[opno] = pattern;
2071 	  return NULL;
2072 	}
2073       else
2074 	{
2075 	  /* Compare predicates before replacing with match_dup.  */
2076 	  if (strcmp (XSTR (pattern, 1),
2077 		      XSTR (match_operand_entries_in_pattern[opno], 1)))
2078 	    {
2079 	      error ("duplicated match_operands with different predicates were"
2080 		     " found.");
2081 	      return NULL;
2082 	    }
2083 	  return generate_match_dup (opno);
2084 	}
2085     }
2086   fmt = GET_RTX_FORMAT (GET_CODE (pattern));
2087   len = GET_RTX_LENGTH (GET_CODE (pattern));
2088   for (i = 0; i < len; i++)
2089     {
2090       switch (fmt[i])
2091 	{
2092 	case 'e': case 'u':
2093 	  mdup = replace_duplicating_operands_in_pattern (XEXP (pattern, i));
2094 	  if (mdup)
2095 	    XEXP (pattern, i) = mdup;
2096 	  break;
2097 	case 'E':
2098 	  for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
2099 	    {
2100 	      mdup =
2101 		replace_duplicating_operands_in_pattern (XVECEXP
2102 							 (pattern, i, j));
2103 	      if (mdup)
2104 		XVECEXP (pattern, i, j) = mdup;
2105 	    }
2106 	  break;
2107 	}
2108     }
2109   return NULL;
2110 }
2111 
2112 /* The routine modifies given input PATTERN of define_subst, replacing
2113    MATCH_DUP and MATCH_OP_DUP with operands from define_insn original
2114    pattern, whose operands are stored in OPERAND_DATA array.
2115    It also duplicates constraints in operands - constraints from
2116    define_insn operands are duplicated N_SUBST_ALT times, constraints
2117    from define_subst operands are duplicated N_ALT times.
2118    After the duplication, returned output rtl-pattern contains every
2119    combination of input constraints Vs constraints from define_subst
2120    output.  */
2121 static rtx
subst_dup(rtx pattern,int n_alt,int n_subst_alt)2122 subst_dup (rtx pattern, int n_alt, int n_subst_alt)
2123 {
2124   const char *fmt;
2125   enum rtx_code code;
2126   int i, j, len, opno;
2127 
2128   code = GET_CODE (pattern);
2129   switch (code)
2130     {
2131     case MATCH_DUP:
2132     case MATCH_OP_DUP:
2133       opno = XINT (pattern, 0);
2134 
2135       gcc_assert (opno >= 0 && opno < MAX_OPERANDS);
2136 
2137       if (operand_data[opno])
2138 	{
2139 	  pattern = copy_rtx (operand_data[opno]);
2140 
2141 	  /* Duplicate constraints.  */
2142 	  pattern = alter_constraints (pattern, n_subst_alt,
2143 				       duplicate_alternatives);
2144 	}
2145       break;
2146 
2147     default:
2148       break;
2149     }
2150 
2151   fmt = GET_RTX_FORMAT (GET_CODE (pattern));
2152   len = GET_RTX_LENGTH (GET_CODE (pattern));
2153   for (i = 0; i < len; i++)
2154     {
2155       switch (fmt[i])
2156 	{
2157 	case 'e': case 'u':
2158 	  if (code != MATCH_DUP && code != MATCH_OP_DUP)
2159 	    XEXP (pattern, i) = subst_dup (XEXP (pattern, i),
2160 					   n_alt, n_subst_alt);
2161 	  break;
2162 	case 'V':
2163 	  if (XVEC (pattern, i) == NULL)
2164 	    break;
2165 	case 'E':
2166 	  for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
2167 	    if (code != MATCH_DUP && code != MATCH_OP_DUP)
2168 	      XVECEXP (pattern, i, j) = subst_dup (XVECEXP (pattern, i, j),
2169 						   n_alt, n_subst_alt);
2170 	  break;
2171 
2172 	case 'i': case 'w': case '0': case 's': case 'S': case 'T':
2173 	  break;
2174 
2175 	default:
2176 	  gcc_unreachable ();
2177 	}
2178     }
2179   return pattern;
2180 }
2181 
2182 /* If we have any DEFINE_COND_EXEC patterns, expand the DEFINE_INSN
2183    patterns appropriately.  */
2184 
2185 static void
process_define_cond_exec(void)2186 process_define_cond_exec (void)
2187 {
2188   struct queue_elem *elem;
2189 
2190   identify_predicable_attribute ();
2191   if (have_error)
2192     return;
2193 
2194   for (elem = define_cond_exec_queue; elem ; elem = elem->next)
2195     process_one_cond_exec (elem);
2196 }
2197 
2198 /* If we have any DEFINE_SUBST patterns, expand DEFINE_INSN and
2199    DEFINE_EXPAND patterns appropriately.  */
2200 
2201 static void
process_define_subst(void)2202 process_define_subst (void)
2203 {
2204   struct queue_elem *elem, *elem_attr;
2205 
2206   /* Check if each define_subst has corresponding define_subst_attr.  */
2207   for (elem = define_subst_queue; elem ; elem = elem->next)
2208     {
2209       for (elem_attr = define_subst_attr_queue;
2210 	   elem_attr;
2211 	   elem_attr = elem_attr->next)
2212 	if (strcmp (XSTR (elem->data, 0), XSTR (elem_attr->data, 1)) == 0)
2213 	    goto found;
2214 
2215 	error_with_line (elem->lineno,
2216 			 "%s: `define_subst' must have at least one "
2217 			 "corresponding `define_subst_attr'",
2218 			 XSTR (elem->data, 0));
2219 	return;
2220       found:
2221 	continue;
2222     }
2223 
2224   for (elem = define_insn_queue; elem ; elem = elem->next)
2225     process_substs_on_one_elem (elem, define_insn_queue);
2226   for (elem = other_queue; elem ; elem = elem->next)
2227     {
2228       if (GET_CODE (elem->data) != DEFINE_EXPAND)
2229 	continue;
2230       process_substs_on_one_elem (elem, other_queue);
2231     }
2232 }
2233 
2234 /* A read_md_files callback for reading an rtx.  */
2235 
2236 static void
rtx_handle_directive(int lineno,const char * rtx_name)2237 rtx_handle_directive (int lineno, const char *rtx_name)
2238 {
2239   rtx queue, x;
2240 
2241   if (read_rtx (rtx_name, &queue))
2242     for (x = queue; x; x = XEXP (x, 1))
2243       process_rtx (XEXP (x, 0), lineno);
2244 }
2245 
2246 /* Comparison function for the mnemonic hash table.  */
2247 
2248 static int
htab_eq_string(const void * s1,const void * s2)2249 htab_eq_string (const void *s1, const void *s2)
2250 {
2251   return strcmp ((const char*)s1, (const char*)s2) == 0;
2252 }
2253 
2254 /* Add mnemonic STR with length LEN to the mnemonic hash table
2255    MNEMONIC_HTAB.  A trailing zero end character is appendend to STR
2256    and a permanent heap copy of STR is created.  */
2257 
2258 static void
add_mnemonic_string(htab_t mnemonic_htab,const char * str,int len)2259 add_mnemonic_string (htab_t mnemonic_htab, const char *str, int len)
2260 {
2261   char *new_str;
2262   void **slot;
2263   char *str_zero = (char*)alloca (len + 1);
2264 
2265   memcpy (str_zero, str, len);
2266   str_zero[len] = '\0';
2267 
2268   slot = htab_find_slot (mnemonic_htab, str_zero, INSERT);
2269 
2270   if (*slot)
2271     return;
2272 
2273   /* Not found; create a permanent copy and add it to the hash table.  */
2274   new_str = XNEWVAR (char, len + 1);
2275   memcpy (new_str, str_zero, len + 1);
2276   *slot = new_str;
2277 }
2278 
2279 /* Scan INSN for mnemonic strings and add them to the mnemonic hash
2280    table in MNEMONIC_HTAB.
2281 
2282    The mnemonics cannot be found if they are emitted using C code.
2283 
2284    If a mnemonic string contains ';' or a newline the string assumed
2285    to consist of more than a single instruction.  The attribute value
2286    will then be set to the user defined default value.  */
2287 
2288 static void
gen_mnemonic_setattr(htab_t mnemonic_htab,rtx insn)2289 gen_mnemonic_setattr (htab_t mnemonic_htab, rtx insn)
2290 {
2291   const char *template_code, *cp;
2292   int i;
2293   int vec_len;
2294   rtx set_attr;
2295   char *attr_name;
2296   rtvec new_vec;
2297 
2298   template_code = XTMPL (insn, 3);
2299 
2300   /* Skip patterns which use C code to emit the template.  */
2301   if (template_code[0] == '*')
2302     return;
2303 
2304   if (template_code[0] == '@')
2305     cp = &template_code[1];
2306   else
2307     cp = &template_code[0];
2308 
2309   for (i = 0; *cp; )
2310     {
2311       const char *ep, *sp;
2312       int size = 0;
2313 
2314       while (ISSPACE (*cp))
2315 	cp++;
2316 
2317       for (ep = sp = cp; !IS_VSPACE (*ep) && *ep != '\0'; ++ep)
2318 	if (!ISSPACE (*ep))
2319 	  sp = ep + 1;
2320 
2321       if (i > 0)
2322 	obstack_1grow (&string_obstack, ',');
2323 
2324       while (cp < sp && ((*cp >= '0' && *cp <= '9')
2325 			 || (*cp >= 'a' && *cp <= 'z')))
2326 
2327 	{
2328 	  obstack_1grow (&string_obstack, *cp);
2329 	  cp++;
2330 	  size++;
2331 	}
2332 
2333       while (cp < sp)
2334 	{
2335 	  if (*cp == ';' || (*cp == '\\' && cp[1] == 'n'))
2336 	    {
2337 	      /* Don't set a value if there are more than one
2338 		 instruction in the string.  */
2339 	      obstack_next_free (&string_obstack) =
2340 		obstack_next_free (&string_obstack) - size;
2341 	      size = 0;
2342 
2343 	      cp = sp;
2344 	      break;
2345 	    }
2346 	  cp++;
2347 	}
2348       if (size == 0)
2349 	obstack_1grow (&string_obstack, '*');
2350       else
2351 	add_mnemonic_string (mnemonic_htab,
2352 			     obstack_next_free (&string_obstack) - size,
2353 			     size);
2354       i++;
2355     }
2356 
2357   /* An insn definition might emit an empty string.  */
2358   if (obstack_object_size (&string_obstack) == 0)
2359     return;
2360 
2361   obstack_1grow (&string_obstack, '\0');
2362 
2363   set_attr = rtx_alloc (SET_ATTR);
2364   XSTR (set_attr, 1) = XOBFINISH (&string_obstack, char *);
2365   attr_name = XNEWVAR (char, strlen (MNEMONIC_ATTR_NAME) + 1);
2366   strcpy (attr_name, MNEMONIC_ATTR_NAME);
2367   XSTR (set_attr, 0) = attr_name;
2368 
2369   if (!XVEC (insn, 4))
2370     vec_len = 0;
2371   else
2372     vec_len = XVECLEN (insn, 4);
2373 
2374   new_vec = rtvec_alloc (vec_len + 1);
2375   for (i = 0; i < vec_len; i++)
2376     RTVEC_ELT (new_vec, i) = XVECEXP (insn, 4, i);
2377   RTVEC_ELT (new_vec, vec_len) = set_attr;
2378   XVEC (insn, 4) = new_vec;
2379 }
2380 
2381 /* This function is called for the elements in the mnemonic hashtable
2382    and generates a comma separated list of the mnemonics.  */
2383 
2384 static int
mnemonic_htab_callback(void ** slot,void * info ATTRIBUTE_UNUSED)2385 mnemonic_htab_callback (void **slot, void *info ATTRIBUTE_UNUSED)
2386 {
2387   obstack_grow (&string_obstack, (char*)*slot, strlen ((char*)*slot));
2388   obstack_1grow (&string_obstack, ',');
2389   return 1;
2390 }
2391 
2392 /* Generate (set_attr "mnemonic" "..") RTXs and append them to every
2393    insn definition in case the back end requests it by defining the
2394    mnemonic attribute.  The values for the attribute will be extracted
2395    from the output patterns of the insn definitions as far as
2396    possible.  */
2397 
2398 static void
gen_mnemonic_attr(void)2399 gen_mnemonic_attr (void)
2400 {
2401   struct queue_elem *elem;
2402   rtx mnemonic_attr = NULL;
2403   htab_t mnemonic_htab;
2404   const char *str, *p;
2405   int i;
2406 
2407   if (have_error)
2408     return;
2409 
2410   /* Look for the DEFINE_ATTR for `mnemonic'.  */
2411   for (elem = define_attr_queue; elem != *define_attr_tail; elem = elem->next)
2412     if (GET_CODE (elem->data) == DEFINE_ATTR
2413 	&& strcmp (XSTR (elem->data, 0), MNEMONIC_ATTR_NAME) == 0)
2414       {
2415 	mnemonic_attr = elem->data;
2416 	break;
2417       }
2418 
2419   /* A (define_attr "mnemonic" "...") indicates that the back-end
2420      wants a mnemonic attribute to be generated.  */
2421   if (!mnemonic_attr)
2422     return;
2423 
2424   mnemonic_htab = htab_create_alloc (MNEMONIC_HTAB_SIZE, htab_hash_string,
2425 				     htab_eq_string, 0, xcalloc, free);
2426 
2427   for (elem = define_insn_queue; elem; elem = elem->next)
2428     {
2429       rtx insn = elem->data;
2430       bool found = false;
2431 
2432       /* Check if the insn definition already has
2433 	 (set_attr "mnemonic" ...).  */
2434       if (XVEC (insn, 4))
2435  	for (i = 0; i < XVECLEN (insn, 4); i++)
2436 	  if (strcmp (XSTR (XVECEXP (insn, 4, i), 0), MNEMONIC_ATTR_NAME) == 0)
2437 	    {
2438 	      found = true;
2439 	      break;
2440 	    }
2441 
2442       if (!found)
2443 	gen_mnemonic_setattr (mnemonic_htab, insn);
2444     }
2445 
2446   /* Add the user defined values to the hash table.  */
2447   str = XSTR (mnemonic_attr, 1);
2448   while ((p = scan_comma_elt (&str)) != NULL)
2449     add_mnemonic_string (mnemonic_htab, p, str - p);
2450 
2451   htab_traverse (mnemonic_htab, mnemonic_htab_callback, NULL);
2452 
2453   /* Replace the last ',' with the zero end character.  */
2454   *((char *)obstack_next_free (&string_obstack) - 1) = '\0';
2455   XSTR (mnemonic_attr, 1) = XOBFINISH (&string_obstack, char *);
2456 }
2457 
2458 /* Check if there are DEFINE_ATTRs with the same name.  */
2459 static void
check_define_attr_duplicates()2460 check_define_attr_duplicates ()
2461 {
2462   struct queue_elem *elem;
2463   htab_t attr_htab;
2464   char * attr_name;
2465   void **slot;
2466 
2467   attr_htab = htab_create (500, htab_hash_string, htab_eq_string, NULL);
2468 
2469   for (elem = define_attr_queue; elem; elem = elem->next)
2470     {
2471       attr_name = xstrdup (XSTR (elem->data, 0));
2472 
2473       slot = htab_find_slot (attr_htab, attr_name, INSERT);
2474 
2475       /* Duplicate.  */
2476       if (*slot)
2477 	{
2478 	  error_with_line (elem->lineno, "redefinition of attribute '%s'",
2479 			   attr_name);
2480 	  htab_delete (attr_htab);
2481 	  return;
2482 	}
2483 
2484       *slot = attr_name;
2485     }
2486 
2487   htab_delete (attr_htab);
2488 }
2489 
2490 /* The entry point for initializing the reader.  */
2491 
2492 bool
init_rtx_reader_args_cb(int argc,char ** argv,bool (* parse_opt)(const char *))2493 init_rtx_reader_args_cb (int argc, char **argv,
2494 			 bool (*parse_opt) (const char *))
2495 {
2496   /* Prepare to read input.  */
2497   condition_table = htab_create (500, hash_c_test, cmp_c_test, NULL);
2498   init_predicate_table ();
2499   obstack_init (rtl_obstack);
2500 
2501   /* Start at 1, to make 0 available for CODE_FOR_nothing.  */
2502   sequence_num = 1;
2503 
2504   read_md_files (argc, argv, parse_opt, rtx_handle_directive);
2505 
2506   if (define_attr_queue != NULL)
2507     check_define_attr_duplicates ();
2508 
2509   /* Process define_cond_exec patterns.  */
2510   if (define_cond_exec_queue != NULL)
2511     process_define_cond_exec ();
2512 
2513   /* Process define_subst patterns.  */
2514   if (define_subst_queue != NULL)
2515     process_define_subst ();
2516 
2517   if (define_attr_queue != NULL)
2518     gen_mnemonic_attr ();
2519 
2520   return !have_error;
2521 }
2522 
2523 /* Programs that don't have their own options can use this entry point
2524    instead.  */
2525 bool
init_rtx_reader_args(int argc,char ** argv)2526 init_rtx_reader_args (int argc, char **argv)
2527 {
2528   return init_rtx_reader_args_cb (argc, argv, 0);
2529 }
2530 
2531 /* The entry point for reading a single rtx from an md file.  Return
2532    the rtx, or NULL if the md file has been fully processed.
2533    Return the line where the rtx was found in LINENO.
2534    Return the number of code generating rtx'en read since the start
2535    of the md file in SEQNR.  */
2536 
2537 rtx
read_md_rtx(int * lineno,int * seqnr)2538 read_md_rtx (int *lineno, int *seqnr)
2539 {
2540   struct queue_elem **queue, *elem;
2541   rtx desc;
2542 
2543  discard:
2544 
2545   /* Read all patterns from a given queue before moving on to the next.  */
2546   if (define_attr_queue != NULL)
2547     queue = &define_attr_queue;
2548   else if (define_pred_queue != NULL)
2549     queue = &define_pred_queue;
2550   else if (define_insn_queue != NULL)
2551     queue = &define_insn_queue;
2552   else if (other_queue != NULL)
2553     queue = &other_queue;
2554   else
2555     return NULL_RTX;
2556 
2557   elem = *queue;
2558   *queue = elem->next;
2559   desc = elem->data;
2560   read_md_filename = elem->filename;
2561   *lineno = elem->lineno;
2562   *seqnr = sequence_num;
2563 
2564   free (elem);
2565 
2566   /* Discard insn patterns which we know can never match (because
2567      their C test is provably always false).  If insn_elision is
2568      false, our caller needs to see all the patterns.  Note that the
2569      elided patterns are never counted by the sequence numbering; it
2570      is the caller's responsibility, when insn_elision is false, not
2571      to use elided pattern numbers for anything.  */
2572   switch (GET_CODE (desc))
2573     {
2574     case DEFINE_INSN:
2575     case DEFINE_EXPAND:
2576     case DEFINE_SUBST:
2577       if (maybe_eval_c_test (XSTR (desc, 2)) != 0)
2578 	sequence_num++;
2579       else if (insn_elision)
2580 	goto discard;
2581 
2582       /* *seqnr is used here so the name table will match caller's
2583 	 idea of insn numbering, whether or not elision is active.  */
2584       record_insn_name (*seqnr, XSTR (desc, 0));
2585       break;
2586 
2587     case DEFINE_SPLIT:
2588     case DEFINE_PEEPHOLE:
2589     case DEFINE_PEEPHOLE2:
2590       if (maybe_eval_c_test (XSTR (desc, 1)) != 0)
2591 	sequence_num++;
2592       else if (insn_elision)
2593 	    goto discard;
2594       break;
2595 
2596     default:
2597       break;
2598     }
2599 
2600   return desc;
2601 }
2602 
2603 /* Helper functions for insn elision.  */
2604 
2605 /* Compute a hash function of a c_test structure, which is keyed
2606    by its ->expr field.  */
2607 hashval_t
hash_c_test(const void * x)2608 hash_c_test (const void *x)
2609 {
2610   const struct c_test *a = (const struct c_test *) x;
2611   const unsigned char *base, *s = (const unsigned char *) a->expr;
2612   hashval_t hash;
2613   unsigned char c;
2614   unsigned int len;
2615 
2616   base = s;
2617   hash = 0;
2618 
2619   while ((c = *s++) != '\0')
2620     {
2621       hash += c + (c << 17);
2622       hash ^= hash >> 2;
2623     }
2624 
2625   len = s - base;
2626   hash += len + (len << 17);
2627   hash ^= hash >> 2;
2628 
2629   return hash;
2630 }
2631 
2632 /* Compare two c_test expression structures.  */
2633 int
cmp_c_test(const void * x,const void * y)2634 cmp_c_test (const void *x, const void *y)
2635 {
2636   const struct c_test *a = (const struct c_test *) x;
2637   const struct c_test *b = (const struct c_test *) y;
2638 
2639   return !strcmp (a->expr, b->expr);
2640 }
2641 
2642 /* Given a string representing a C test expression, look it up in the
2643    condition_table and report whether or not its value is known
2644    at compile time.  Returns a tristate: 1 for known true, 0 for
2645    known false, -1 for unknown.  */
2646 int
maybe_eval_c_test(const char * expr)2647 maybe_eval_c_test (const char *expr)
2648 {
2649   const struct c_test *test;
2650   struct c_test dummy;
2651 
2652   if (expr[0] == 0)
2653     return 1;
2654 
2655   dummy.expr = expr;
2656   test = (const struct c_test *)htab_find (condition_table, &dummy);
2657   if (!test)
2658     return -1;
2659   return test->value;
2660 }
2661 
2662 /* Record the C test expression EXPR in the condition_table, with
2663    value VAL.  Duplicates clobber previous entries.  */
2664 
2665 void
add_c_test(const char * expr,int value)2666 add_c_test (const char *expr, int value)
2667 {
2668   struct c_test *test;
2669 
2670   if (expr[0] == 0)
2671     return;
2672 
2673   test = XNEW (struct c_test);
2674   test->expr = expr;
2675   test->value = value;
2676 
2677   *(htab_find_slot (condition_table, test, INSERT)) = test;
2678 }
2679 
2680 /* For every C test, call CALLBACK with two arguments: a pointer to
2681    the condition structure and INFO.  Stops when CALLBACK returns zero.  */
2682 void
traverse_c_tests(htab_trav callback,void * info)2683 traverse_c_tests (htab_trav callback, void *info)
2684 {
2685   if (condition_table)
2686     htab_traverse (condition_table, callback, info);
2687 }
2688 
2689 /* Helper functions for define_predicate and define_special_predicate
2690    processing.  Shared between genrecog.c and genpreds.c.  */
2691 
2692 static htab_t predicate_table;
2693 struct pred_data *first_predicate;
2694 static struct pred_data **last_predicate = &first_predicate;
2695 
2696 static hashval_t
hash_struct_pred_data(const void * ptr)2697 hash_struct_pred_data (const void *ptr)
2698 {
2699   return htab_hash_string (((const struct pred_data *)ptr)->name);
2700 }
2701 
2702 static int
eq_struct_pred_data(const void * a,const void * b)2703 eq_struct_pred_data (const void *a, const void *b)
2704 {
2705   return !strcmp (((const struct pred_data *)a)->name,
2706 		  ((const struct pred_data *)b)->name);
2707 }
2708 
2709 struct pred_data *
lookup_predicate(const char * name)2710 lookup_predicate (const char *name)
2711 {
2712   struct pred_data key;
2713   key.name = name;
2714   return (struct pred_data *) htab_find (predicate_table, &key);
2715 }
2716 
2717 /* Record that predicate PRED can accept CODE.  */
2718 
2719 void
add_predicate_code(struct pred_data * pred,enum rtx_code code)2720 add_predicate_code (struct pred_data *pred, enum rtx_code code)
2721 {
2722   if (!pred->codes[code])
2723     {
2724       pred->num_codes++;
2725       pred->codes[code] = true;
2726 
2727       if (GET_RTX_CLASS (code) != RTX_CONST_OBJ)
2728 	pred->allows_non_const = true;
2729 
2730       if (code != REG
2731 	  && code != SUBREG
2732 	  && code != MEM
2733 	  && code != CONCAT
2734 	  && code != PARALLEL
2735 	  && code != STRICT_LOW_PART)
2736 	pred->allows_non_lvalue = true;
2737 
2738       if (pred->num_codes == 1)
2739 	pred->singleton = code;
2740       else if (pred->num_codes == 2)
2741 	pred->singleton = UNKNOWN;
2742     }
2743 }
2744 
2745 void
add_predicate(struct pred_data * pred)2746 add_predicate (struct pred_data *pred)
2747 {
2748   void **slot = htab_find_slot (predicate_table, pred, INSERT);
2749   if (*slot)
2750     {
2751       error ("duplicate predicate definition for '%s'", pred->name);
2752       return;
2753     }
2754   *slot = pred;
2755   *last_predicate = pred;
2756   last_predicate = &pred->next;
2757 }
2758 
2759 /* This array gives the initial content of the predicate table.  It
2760    has entries for all predicates defined in recog.c.  */
2761 
2762 struct std_pred_table
2763 {
2764   const char *name;
2765   bool special;
2766   bool allows_const_p;
2767   RTX_CODE codes[NUM_RTX_CODE];
2768 };
2769 
2770 static const struct std_pred_table std_preds[] = {
2771   {"general_operand", false, true, {SUBREG, REG, MEM}},
2772   {"address_operand", true, true, {SUBREG, REG, MEM, PLUS, MINUS, MULT}},
2773   {"register_operand", false, false, {SUBREG, REG}},
2774   {"pmode_register_operand", true, false, {SUBREG, REG}},
2775   {"scratch_operand", false, false, {SCRATCH, REG}},
2776   {"immediate_operand", false, true, {UNKNOWN}},
2777   {"const_int_operand", false, false, {CONST_INT}},
2778   {"const_double_operand", false, false, {CONST_INT, CONST_DOUBLE}},
2779   {"nonimmediate_operand", false, false, {SUBREG, REG, MEM}},
2780   {"nonmemory_operand", false, true, {SUBREG, REG}},
2781   {"push_operand", false, false, {MEM}},
2782   {"pop_operand", false, false, {MEM}},
2783   {"memory_operand", false, false, {SUBREG, MEM}},
2784   {"indirect_operand", false, false, {SUBREG, MEM}},
2785   {"ordered_comparison_operator", false, false, {EQ, NE,
2786 						 LE, LT, GE, GT,
2787 						 LEU, LTU, GEU, GTU}},
2788   {"comparison_operator", false, false, {EQ, NE,
2789 					 LE, LT, GE, GT,
2790 					 LEU, LTU, GEU, GTU,
2791 					 UNORDERED, ORDERED,
2792 					 UNEQ, UNGE, UNGT,
2793 					 UNLE, UNLT, LTGT}}
2794 };
2795 #define NUM_KNOWN_STD_PREDS ARRAY_SIZE (std_preds)
2796 
2797 /* Initialize the table of predicate definitions, starting with
2798    the information we have on generic predicates.  */
2799 
2800 static void
init_predicate_table(void)2801 init_predicate_table (void)
2802 {
2803   size_t i, j;
2804   struct pred_data *pred;
2805 
2806   predicate_table = htab_create_alloc (37, hash_struct_pred_data,
2807 				       eq_struct_pred_data, 0,
2808 				       xcalloc, free);
2809 
2810   for (i = 0; i < NUM_KNOWN_STD_PREDS; i++)
2811     {
2812       pred = XCNEW (struct pred_data);
2813       pred->name = std_preds[i].name;
2814       pred->special = std_preds[i].special;
2815 
2816       for (j = 0; std_preds[i].codes[j] != 0; j++)
2817 	add_predicate_code (pred, std_preds[i].codes[j]);
2818 
2819       if (std_preds[i].allows_const_p)
2820 	for (j = 0; j < NUM_RTX_CODE; j++)
2821 	  if (GET_RTX_CLASS (j) == RTX_CONST_OBJ)
2822 	    add_predicate_code (pred, (enum rtx_code) j);
2823 
2824       add_predicate (pred);
2825     }
2826 }
2827 
2828 /* These functions allow linkage with print-rtl.c.  Also, some generators
2829    like to annotate their output with insn names.  */
2830 
2831 /* Holds an array of names indexed by insn_code_number.  */
2832 static char **insn_name_ptr = 0;
2833 static int insn_name_ptr_size = 0;
2834 
2835 const char *
get_insn_name(int code)2836 get_insn_name (int code)
2837 {
2838   if (code < insn_name_ptr_size)
2839     return insn_name_ptr[code];
2840   else
2841     return NULL;
2842 }
2843 
2844 static void
record_insn_name(int code,const char * name)2845 record_insn_name (int code, const char *name)
2846 {
2847   static const char *last_real_name = "insn";
2848   static int last_real_code = 0;
2849   char *new_name;
2850 
2851   if (insn_name_ptr_size <= code)
2852     {
2853       int new_size;
2854       new_size = (insn_name_ptr_size ? insn_name_ptr_size * 2 : 512);
2855       insn_name_ptr = XRESIZEVEC (char *, insn_name_ptr, new_size);
2856       memset (insn_name_ptr + insn_name_ptr_size, 0,
2857 	      sizeof(char *) * (new_size - insn_name_ptr_size));
2858       insn_name_ptr_size = new_size;
2859     }
2860 
2861   if (!name || name[0] == '\0')
2862     {
2863       new_name = XNEWVAR (char, strlen (last_real_name) + 10);
2864       sprintf (new_name, "%s+%d", last_real_name, code - last_real_code);
2865     }
2866   else
2867     {
2868       last_real_name = new_name = xstrdup (name);
2869       last_real_code = code;
2870     }
2871 
2872   insn_name_ptr[code] = new_name;
2873 }
2874 
2875 /* Make STATS describe the operands that appear in rtx X.  */
2876 
2877 static void
get_pattern_stats_1(struct pattern_stats * stats,rtx x)2878 get_pattern_stats_1 (struct pattern_stats *stats, rtx x)
2879 {
2880   RTX_CODE code;
2881   int i;
2882   int len;
2883   const char *fmt;
2884 
2885   if (x == NULL_RTX)
2886     return;
2887 
2888   code = GET_CODE (x);
2889   switch (code)
2890     {
2891     case MATCH_OPERAND:
2892     case MATCH_OPERATOR:
2893     case MATCH_PARALLEL:
2894       stats->max_opno = MAX (stats->max_opno, XINT (x, 0));
2895       break;
2896 
2897     case MATCH_DUP:
2898     case MATCH_OP_DUP:
2899     case MATCH_PAR_DUP:
2900       stats->num_dups++;
2901       stats->max_dup_opno = MAX (stats->max_dup_opno, XINT (x, 0));
2902       break;
2903 
2904     case MATCH_SCRATCH:
2905       stats->max_scratch_opno = MAX (stats->max_scratch_opno, XINT (x, 0));
2906       break;
2907 
2908     default:
2909       break;
2910     }
2911 
2912   fmt = GET_RTX_FORMAT (code);
2913   len = GET_RTX_LENGTH (code);
2914   for (i = 0; i < len; i++)
2915     {
2916       if (fmt[i] == 'e' || fmt[i] == 'u')
2917 	get_pattern_stats_1 (stats, XEXP (x, i));
2918       else if (fmt[i] == 'E')
2919 	{
2920 	  int j;
2921 	  for (j = 0; j < XVECLEN (x, i); j++)
2922 	    get_pattern_stats_1 (stats, XVECEXP (x, i, j));
2923 	}
2924     }
2925 }
2926 
2927 /* Make STATS describe the operands that appear in instruction pattern
2928    PATTERN.  */
2929 
2930 void
get_pattern_stats(struct pattern_stats * stats,rtvec pattern)2931 get_pattern_stats (struct pattern_stats *stats, rtvec pattern)
2932 {
2933   int i, len;
2934 
2935   stats->max_opno = -1;
2936   stats->max_dup_opno = -1;
2937   stats->max_scratch_opno = -1;
2938   stats->num_dups = 0;
2939 
2940   len = GET_NUM_ELEM (pattern);
2941   for (i = 0; i < len; i++)
2942     get_pattern_stats_1 (stats, RTVEC_ELT (pattern, i));
2943 
2944   stats->num_generator_args = stats->max_opno + 1;
2945   stats->num_insn_operands = MAX (stats->max_opno,
2946 				  stats->max_scratch_opno) + 1;
2947   stats->num_operand_vars = MAX (stats->max_opno,
2948 				  MAX (stats->max_dup_opno,
2949 				       stats->max_scratch_opno)) + 1;
2950 }
2951