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