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