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