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