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