ada: Fix wrong finalization for call to BIP function in conditional expression
[official-gcc.git] / gcc / gensupport.cc
blobf9efc6eb7572a44b8bb154b0b22be3815bd0d244
1 /* Support routines for the various generation passes.
2 Copyright (C) 2000-2023 Free Software Foundation, Inc.
4 This file is part of GCC.
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.
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.
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/>. */
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"
31 #define MAX_OPERANDS 40
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];
38 /* In case some macros used by files we include need it, define this here. */
39 int target_flags;
41 int insn_elision = 1;
43 static struct obstack obstack;
44 struct obstack *rtl_obstack = &obstack;
46 /* Counter for named patterns and INSN_CODEs. */
47 static int insn_sequence_num;
49 /* Counter for define_splits. */
50 static int split_sequence_num;
52 /* Counter for define_peephole2s. */
53 static int peephole2_sequence_num;
55 static int predicable_default;
56 static const char *predicable_true;
57 static const char *predicable_false;
59 static const char *subst_true = "yes";
60 static const char *subst_false = "no";
62 static htab_t condition_table;
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. */
68 class queue_elem
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;
79 #define MNEMONIC_ATTR_NAME "mnemonic"
80 #define MNEMONIC_HTAB_SIZE 1024
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;
97 /* Mapping from DEFINE_* rtxes to their location in the source file. */
98 static hash_map <rtx, file_location> *rtx_locs;
100 static void remove_constraints (rtx);
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 *);
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);
125 static const char * duplicate_alternatives (const char *, int);
126 static const char * duplicate_each_alternative (const char * str, int n_dup);
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);
133 /* Make a version of gen_rtx_CONST_INT so that GEN_INT can be used in
134 the gensupport programs. */
137 gen_rtx_CONST_INT (machine_mode ARG_UNUSED (mode),
138 HOST_WIDE_INT arg)
140 rtx rt = rtx_alloc (CONST_INT);
142 XWINT (rt, 0) = arg;
143 return rt;
146 /* Return the rtx pattern specified by the list of rtxes in a
147 define_insn or define_split. */
150 add_implicit_parallel (rtvec vec)
152 if (GET_NUM_ELEM (vec) == 1)
153 return RTVEC_ELT (vec, 0);
154 else
156 rtx pattern = rtx_alloc (PARALLEL);
157 XVEC (pattern, 0) = vec;
158 return pattern;
162 /* Predicate handling.
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.
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.
176 validate_pattern will warn about predicates that allow non-lvalues
177 when they appear in destination operands.
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.
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
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. */
198 #define N 0
199 #define Y 1
200 #define I 2
202 #define TRISTATE_AND(a,b) \
203 ((a) == I ? ((b) == N ? N : I) : \
204 (b) == I ? ((a) == N ? N : I) : \
205 (a) && (b))
207 #define TRISTATE_OR(a,b) \
208 ((a) == I ? ((b) == Y ? Y : I) : \
209 (b) == I ? ((a) == Y ? Y : I) : \
210 (a) || (b))
212 #define TRISTATE_NOT(a) \
213 ((a) == I ? I : !(a))
215 /* 0 means no warning about that code yet, 1 means warned. */
216 static char did_you_mean_codes[NUM_RTX_CODE];
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. */
222 void
223 compute_test_codes (rtx exp, file_location loc, char *codes)
225 char op0_codes[NUM_RTX_CODE];
226 char op1_codes[NUM_RTX_CODE];
227 char op2_codes[NUM_RTX_CODE];
228 int i;
230 switch (GET_CODE (exp))
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;
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;
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;
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')
268 memset (codes, Y, NUM_RTX_CODE);
269 break;
272 memset (codes, N, NUM_RTX_CODE);
274 const char *next_code = XSTR (exp, 0);
275 const char *code;
277 if (*next_code == '\0')
279 error_at (loc, "empty match_code expression");
280 break;
283 while ((code = scan_comma_elt (&next_code)) != 0)
285 size_t n = next_code - code;
286 int found_it = 0;
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')
292 codes[i] = Y;
293 found_it = 1;
294 break;
296 if (!found_it)
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])
305 did_you_mean_codes[i] = 1;
306 message_at (loc, "(did you mean \"%s\"?)",
307 GET_RTX_NAME (i));
312 break;
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. */
318 struct pred_data *p = lookup_predicate (XSTR (exp, 1));
319 if (!p)
321 error_at (loc, "reference to unknown predicate '%s'",
322 XSTR (exp, 1));
323 break;
325 for (i = 0; i < NUM_RTX_CODE; i++)
326 codes[i] = p->codes[i] ? I : N;
328 break;
331 case MATCH_TEST:
332 /* (match_test WHATEVER) is completely indeterminate. */
333 memset (codes, I, NUM_RTX_CODE);
334 break;
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;
344 #undef TRISTATE_OR
345 #undef TRISTATE_AND
346 #undef TRISTATE_NOT
348 /* Return true if NAME is a valid predicate name. */
350 static bool
351 valid_predicate_name_p (const char *name)
353 const char *p;
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;
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. */
367 static void
368 process_define_predicate (rtx desc, file_location loc)
370 struct pred_data *pred;
371 char codes[NUM_RTX_CODE];
372 int i;
374 if (!valid_predicate_name_p (XSTR (desc, 0)))
376 error_at (loc, "%s: predicate name must be a valid C function name",
377 XSTR (desc, 0));
378 return;
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;
388 compute_test_codes (XEXP (desc, 1), loc, codes);
390 for (i = 0; i < NUM_RTX_CODE; i++)
391 if (codes[i] != N)
392 add_predicate_code (pred, (enum rtx_code) i);
394 add_predicate (pred);
396 #undef I
397 #undef N
398 #undef Y
400 /* Queue PATTERN on LIST_TAIL. Return the address of the new queue
401 element. */
403 static class queue_elem *
404 queue_pattern (rtx pattern, class queue_elem ***list_tail,
405 file_location loc)
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;
417 /* Remove element ELEM from QUEUE. */
418 static void
419 remove_from_queue (class queue_elem *elem, class queue_elem **queue)
421 class queue_elem *prev, *e;
422 prev = NULL;
423 for (e = *queue; e ; e = e->next)
425 if (e == elem)
426 break;
427 prev = e;
429 if (e == NULL)
430 return;
432 if (prev)
433 prev->next = elem->next;
434 else
435 *queue = elem->next;
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
441 add_define_attr (const char *name)
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;
456 /* Recursively remove constraints from an rtx. */
458 static void
459 remove_constraints (rtx part)
461 int i, j;
462 const char *format_ptr;
464 if (part == 0)
465 return;
467 if (GET_CODE (part) == MATCH_OPERAND)
468 XSTR (part, 2) = "";
469 else if (GET_CODE (part) == MATCH_SCRATCH)
470 XSTR (part, 1) = "";
472 format_ptr = GET_RTX_FORMAT (GET_CODE (part));
474 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
475 switch (*format_ptr++)
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;
489 /* Recursively replace MATCH_OPERANDs with MATCH_DUPs and MATCH_OPERATORs
490 with MATCH_OP_DUPs in X. */
492 static rtx
493 replace_operands_with_dups (rtx x)
495 if (x == 0)
496 return x;
498 rtx newx;
499 if (GET_CODE (x) == MATCH_OPERAND)
501 newx = rtx_alloc (MATCH_DUP);
502 XINT (newx, 0) = XINT (x, 0);
503 x = newx;
505 else if (GET_CODE (x) == MATCH_OPERATOR)
507 newx = rtx_alloc (MATCH_OP_DUP);
508 XINT (newx, 0) = XINT (x, 0);
509 XVEC (newx, 1) = XVEC (x, 2);
510 x = newx;
512 else
513 newx = shallow_copy_rtx (x);
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++)
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)
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));
531 break;
533 return newx;
536 /* Convert matching pattern VEC from a DEFINE_INSN_AND_REWRITE into
537 a sequence that should be generated by the splitter. */
539 static rtvec
540 gen_rewrite_sequence (rtvec vec)
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;
548 /* Process a top level rtx in some way, queuing as appropriate. */
550 static void
551 process_rtx (rtx desc, file_location loc)
553 switch (GET_CODE (desc))
555 case DEFINE_INSN:
556 queue_pattern (desc, &define_insn_tail, loc);
557 break;
559 case DEFINE_COND_EXEC:
560 queue_pattern (desc, &define_cond_exec_tail, loc);
561 break;
563 case DEFINE_SUBST:
564 queue_pattern (desc, &define_subst_tail, loc);
565 break;
567 case DEFINE_SUBST_ATTR:
568 queue_pattern (desc, &define_subst_attr_tail, loc);
569 break;
571 case DEFINE_ATTR:
572 case DEFINE_ENUM_ATTR:
573 queue_pattern (desc, &define_attr_tail, loc);
574 break;
576 case DEFINE_PREDICATE:
577 case DEFINE_SPECIAL_PREDICATE:
578 process_define_predicate (desc, loc);
579 /* Fall through. */
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;
590 case DEFINE_INSN_AND_SPLIT:
591 case DEFINE_INSN_AND_REWRITE:
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);
601 /* Create a split with values from the insn_and_split. */
602 split = rtx_alloc (DEFINE_SPLIT);
604 i = XVECLEN (desc, 1);
605 XVEC (split, 0) = rtvec_alloc (i);
606 while (--i >= 0)
608 XVECEXP (split, 0, i) = copy_rtx (XVECEXP (desc, 1, i));
609 remove_constraints (XVECEXP (split, 0, i));
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] == '&')
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);
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);
630 /* Fix up the DEFINE_INSN. */
631 attr = XVEC (desc, split_code + 1);
632 PUT_CODE (desc, DEFINE_INSN);
633 XVEC (desc, 4) = attr;
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;
642 default:
643 queue_pattern (desc, &other_tail, loc);
644 break;
648 /* Return true if attribute PREDICABLE is true for ELEM, which holds
649 a DEFINE_INSN. */
651 static int
652 is_predicable (class queue_elem *elem)
654 rtvec vec = XVEC (elem->data, 4);
655 const char *value;
656 int i;
658 if (! vec)
659 return predicable_default;
661 for (i = GET_NUM_ELEM (vec) - 1; i >= 0; --i)
663 rtx sub = RTVEC_ELT (vec, i);
664 switch (GET_CODE (sub))
666 case SET_ATTR:
667 if (strcmp (XSTR (sub, 0), "predicable") == 0)
669 value = XSTR (sub, 1);
670 goto found;
672 break;
674 case SET_ATTR_ALTERNATIVE:
675 if (strcmp (XSTR (sub, 0), "predicable") == 0)
677 error_at (elem->loc, "multiple alternatives for `predicable'");
678 return 0;
680 break;
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)
689 value = XSTR (sub, 0);
690 goto found;
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;
699 default:
700 gcc_unreachable ();
704 return predicable_default;
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;
716 error_at (elem->loc, "unknown value `%s' for `predicable' attribute", value);
717 return 0;
720 /* Find attribute SUBST in ELEM and assign NEW_VALUE to it. */
721 static void
722 change_subst_attribute (class queue_elem *elem,
723 class queue_elem *subst_elem,
724 const char *new_value)
726 rtvec attrs_vec = XVEC (elem->data, 4);
727 const char *subst_name = XSTR (subst_elem->data, 0);
728 int i;
730 if (! attrs_vec)
731 return;
733 for (i = GET_NUM_ELEM (attrs_vec) - 1; i >= 0; --i)
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)
740 XSTR (cur_attr, 1) = new_value;
741 return;
746 /* Return true if ELEM has the attribute with the name of DEFINE_SUBST
747 represented by SUBST_ELEM and this attribute has value SUBST_TRUE.
748 DEFINE_SUBST isn't applied to patterns without such attribute. In other
749 words, we suppose the default value of the attribute to be 'no' since it is
750 always generated automatically in read-rtl.cc. */
751 static bool
752 has_subst_attribute (class queue_elem *elem, class queue_elem *subst_elem)
754 rtvec attrs_vec = XVEC (elem->data, 4);
755 const char *value, *subst_name = XSTR (subst_elem->data, 0);
756 int i;
758 if (! attrs_vec)
759 return false;
761 for (i = GET_NUM_ELEM (attrs_vec) - 1; i >= 0; --i)
763 rtx cur_attr = RTVEC_ELT (attrs_vec, i);
764 switch (GET_CODE (cur_attr))
766 case SET_ATTR:
767 if (strcmp (XSTR (cur_attr, 0), subst_name) == 0)
769 value = XSTR (cur_attr, 1);
770 goto found;
772 break;
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)
781 value = XSTR (cur_attr, 0);
782 goto found;
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;
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;
799 default:
800 gcc_unreachable ();
804 return false;
806 found:
807 if (strcmp (value, subst_true) == 0)
808 return true;
809 if (strcmp (value, subst_false) == 0)
810 return false;
812 error_at (elem->loc, "unknown value `%s' for `%s' attribute",
813 value, subst_name);
814 return false;
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
821 subst_pattern_match (rtx x, rtx pt, file_location loc)
823 RTX_CODE code, code_pt;
824 int i, j, len;
825 const char *fmt, *pred_name;
827 code = GET_CODE (x);
828 code_pt = GET_CODE (pt);
830 if (code_pt == MATCH_OPERAND)
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. */
838 if (code == MATCH_OPERAND)
840 pred_name = XSTR (pt, 1);
841 if (pred_name[0] != 0)
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. */
849 gcc_assert (XINT (pt, 0) >= 0 && XINT (pt, 0) < MAX_OPERANDS);
850 operand_data[XINT (pt, 0)] = x;
851 return true;
854 if (code_pt == MATCH_OPERATOR)
856 int x_vecexp_pos = -1;
858 /* Compare modes. */
859 if (GET_MODE (pt) != VOIDmode && GET_MODE (x) != GET_MODE (pt))
860 return false;
862 /* In case X is also match_operator, compare predicates. */
863 if (code == MATCH_OPERATOR)
865 pred_name = XSTR (pt, 1);
866 if (pred_name[0] != 0)
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;
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;
888 /* MATCH_OPERATOR or UNSPEC case. */
889 if (x_vecexp_pos >= 0)
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;
900 /* Ordinary operator. */
901 else
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;
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;
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)
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));
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;
945 fmt = GET_RTX_FORMAT (code_pt);
946 len = GET_RTX_LENGTH (code_pt);
948 for (i = 0; i < len; i++)
950 if (fmt[i] == '0')
951 break;
953 switch (fmt[i])
955 case 'r': case 'p': case 'i': case 'w': case 's':
956 continue;
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':
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;
972 default:
973 gcc_unreachable ();
977 return true;
980 /* Examine the attribute "predicable"; discover its boolean values
981 and its default. */
983 static void
984 identify_predicable_attribute (void)
986 class queue_elem *elem;
987 char *p_true, *p_false;
988 const char *value;
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;
995 error_at (define_cond_exec_queue->loc,
996 "attribute `predicable' not defined");
997 return;
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)
1005 error_at (elem->loc, "attribute `predicable' is not a boolean");
1006 free (p_false);
1007 return;
1009 p_true[-1] = '\0';
1011 predicable_true = p_true;
1012 predicable_false = p_false;
1014 switch (GET_CODE (XEXP (elem->data, 2)))
1016 case CONST_STRING:
1017 value = XSTR (XEXP (elem->data, 2), 0);
1018 break;
1020 case CONST:
1021 error_at (elem->loc, "attribute `predicable' cannot be const");
1022 free (p_false);
1023 return;
1025 default:
1026 error_at (elem->loc,
1027 "attribute `predicable' must have a constant default");
1028 free (p_false);
1029 return;
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
1038 error_at (elem->loc, "unknown value `%s' for `predicable' attribute",
1039 value);
1040 free (p_false);
1044 /* Return the number of alternatives in constraint S. */
1046 static int
1047 n_alternatives (const char *s)
1049 int n = 1;
1051 if (s)
1052 while (*s)
1053 n += (*s++ == ',');
1055 return n;
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
1065 get_alternatives_number (rtx pattern, int *n_alt, file_location loc)
1067 const char *fmt;
1068 enum rtx_code code;
1069 int i, j, len;
1071 if (!n_alt)
1072 return 0;
1074 code = GET_CODE (pattern);
1075 switch (code)
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;
1086 else if (i && i != *n_alt)
1088 error_at (loc, "wrong number of alternatives in operand %d",
1089 XINT (pattern, 0));
1090 return 0;
1093 default:
1094 break;
1097 fmt = GET_RTX_FORMAT (code);
1098 len = GET_RTX_LENGTH (code);
1099 for (i = 0; i < len; i++)
1101 switch (fmt[i])
1103 case 'e': case 'u':
1104 if (!get_alternatives_number (XEXP (pattern, i), n_alt, loc))
1105 return 0;
1106 break;
1108 case 'V':
1109 if (XVEC (pattern, i) == NULL)
1110 break;
1111 /* FALLTHRU */
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;
1119 case 'r': case 'p': case 'i': case 'w':
1120 case '0': case 's': case 'S': case 'T':
1121 break;
1123 default:
1124 gcc_unreachable ();
1127 return 1;
1130 /* Determine how many alternatives there are in INSN, and how many
1131 operands. */
1133 static void
1134 collect_insn_data (rtx pattern, int *palt, int *pmax)
1136 const char *fmt;
1137 enum rtx_code code;
1138 int i, j, len;
1140 code = GET_CODE (pattern);
1141 switch (code)
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. */
1149 case MATCH_OPERATOR:
1150 case MATCH_PARALLEL:
1151 i = XINT (pattern, 0);
1152 if (i > *pmax)
1153 *pmax = i;
1154 break;
1156 default:
1157 break;
1160 fmt = GET_RTX_FORMAT (code);
1161 len = GET_RTX_LENGTH (code);
1162 for (i = 0; i < len; i++)
1164 switch (fmt[i])
1166 case 'e': case 'u':
1167 collect_insn_data (XEXP (pattern, i), palt, pmax);
1168 break;
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;
1179 case 'r': case 'p': case 'i': case 'w':
1180 case '0': case 's': case 'S': case 'T':
1181 break;
1183 default:
1184 gcc_unreachable ();
1189 static rtx
1190 alter_predicate_for_insn (rtx pattern, int alt, int max_op,
1191 file_location loc)
1193 const char *fmt;
1194 enum rtx_code code;
1195 int i, j, len;
1197 code = GET_CODE (pattern);
1198 switch (code)
1200 case MATCH_OPERAND:
1202 const char *c = XSTR (pattern, 2);
1204 if (n_alternatives (c) != 1)
1206 error_at (loc, "too many alternatives for operand %d",
1207 XINT (pattern, 0));
1208 return NULL;
1211 /* Replicate C as needed to fill out ALT alternatives. */
1212 if (c && *c && alt > 1)
1214 size_t c_len = strlen (c);
1215 size_t len = alt * (c_len + 1);
1216 char *new_c = XNEWVEC (char, len);
1218 memcpy (new_c, c, c_len);
1219 for (i = 1; i < alt; ++i)
1221 new_c[i * (c_len + 1) - 1] = ',';
1222 memcpy (&new_c[i * (c_len + 1)], c, c_len);
1224 new_c[len - 1] = '\0';
1225 XSTR (pattern, 2) = new_c;
1228 /* Fall through. */
1230 case MATCH_OPERATOR:
1231 case MATCH_SCRATCH:
1232 case MATCH_PARALLEL:
1233 case MATCH_DUP:
1234 XINT (pattern, 0) += max_op;
1235 break;
1237 default:
1238 break;
1241 fmt = GET_RTX_FORMAT (code);
1242 len = GET_RTX_LENGTH (code);
1243 for (i = 0; i < len; i++)
1245 rtx r;
1247 switch (fmt[i])
1249 case 'e': case 'u':
1250 r = alter_predicate_for_insn (XEXP (pattern, i), alt, max_op, loc);
1251 if (r == NULL)
1252 return r;
1253 break;
1255 case 'E':
1256 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
1258 r = alter_predicate_for_insn (XVECEXP (pattern, i, j),
1259 alt, max_op, loc);
1260 if (r == NULL)
1261 return r;
1263 break;
1265 case 'r': case 'p': case 'i': case 'w': case '0': case 's':
1266 break;
1268 default:
1269 gcc_unreachable ();
1273 return pattern;
1276 /* Duplicate constraints in PATTERN. If pattern is from original
1277 rtl-template, we need to duplicate each alternative - for that we
1278 need to use duplicate_each_alternative () as a functor ALTER.
1279 If pattern is from output-pattern of define_subst, we need to
1280 duplicate constraints in another way - with duplicate_alternatives ().
1281 N_DUP is multiplication factor. */
1282 static rtx
1283 alter_constraints (rtx pattern, int n_dup, constraints_handler_t alter)
1285 const char *fmt;
1286 enum rtx_code code;
1287 int i, j, len;
1289 code = GET_CODE (pattern);
1290 switch (code)
1292 case MATCH_OPERAND:
1293 XSTR (pattern, 2) = alter (XSTR (pattern, 2), n_dup);
1294 break;
1295 case MATCH_SCRATCH:
1296 XSTR (pattern, 1) = alter (XSTR (pattern, 1), n_dup);
1297 break;
1299 default:
1300 break;
1303 fmt = GET_RTX_FORMAT (code);
1304 len = GET_RTX_LENGTH (code);
1305 for (i = 0; i < len; i++)
1307 rtx r;
1309 switch (fmt[i])
1311 case 'e': case 'u':
1312 r = alter_constraints (XEXP (pattern, i), n_dup, alter);
1313 if (r == NULL)
1314 return r;
1315 break;
1317 case 'E':
1318 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
1320 r = alter_constraints (XVECEXP (pattern, i, j), n_dup, alter);
1321 if (r == NULL)
1322 return r;
1324 break;
1326 case 'r': case 'p': case 'i': case 'w': case '0': case 's':
1327 break;
1329 default:
1330 break;
1334 return pattern;
1337 static const char *
1338 alter_test_for_insn (class queue_elem *ce_elem,
1339 class queue_elem *insn_elem)
1341 return rtx_reader_ptr->join_c_conditions (XSTR (ce_elem->data, 1),
1342 XSTR (insn_elem->data, 2));
1345 /* Modify VAL, which is an attribute expression for the "enabled" attribute,
1346 to take "ce_enabled" into account. Return the new expression. */
1347 static rtx
1348 modify_attr_enabled_ce (rtx val)
1350 rtx eq_attr, str;
1351 rtx ite;
1352 eq_attr = rtx_alloc (EQ_ATTR);
1353 ite = rtx_alloc (IF_THEN_ELSE);
1354 str = rtx_alloc (CONST_STRING);
1356 XSTR (eq_attr, 0) = "ce_enabled";
1357 XSTR (eq_attr, 1) = "yes";
1358 XSTR (str, 0) = "no";
1359 XEXP (ite, 0) = eq_attr;
1360 XEXP (ite, 1) = val;
1361 XEXP (ite, 2) = str;
1363 return ite;
1366 /* Alter the attribute vector of INSN, which is a COND_EXEC variant created
1367 from a define_insn pattern. We must modify the "predicable" attribute
1368 to be named "ce_enabled", and also change any "enabled" attribute that's
1369 present so that it takes ce_enabled into account.
1370 We rely on the fact that INSN was created with copy_rtx, and modify data
1371 in-place. */
1373 static void
1374 alter_attrs_for_insn (rtx insn)
1376 static bool global_changes_made = false;
1377 rtvec vec = XVEC (insn, 4);
1378 rtvec new_vec;
1379 rtx val, set;
1380 int num_elem;
1381 int predicable_idx = -1;
1382 int enabled_idx = -1;
1383 int i;
1385 if (! vec)
1386 return;
1388 num_elem = GET_NUM_ELEM (vec);
1389 for (i = num_elem - 1; i >= 0; --i)
1391 rtx sub = RTVEC_ELT (vec, i);
1392 switch (GET_CODE (sub))
1394 case SET_ATTR:
1395 if (strcmp (XSTR (sub, 0), "predicable") == 0)
1397 predicable_idx = i;
1398 XSTR (sub, 0) = "ce_enabled";
1400 else if (strcmp (XSTR (sub, 0), "enabled") == 0)
1402 enabled_idx = i;
1403 XSTR (sub, 0) = "nonce_enabled";
1405 break;
1407 case SET_ATTR_ALTERNATIVE:
1408 if (strcmp (XSTR (sub, 0), "predicable") == 0)
1409 /* We already give an error elsewhere. */
1410 return;
1411 else if (strcmp (XSTR (sub, 0), "enabled") == 0)
1413 enabled_idx = i;
1414 XSTR (sub, 0) = "nonce_enabled";
1416 break;
1418 case SET:
1419 if (GET_CODE (SET_DEST (sub)) != ATTR)
1420 break;
1421 if (strcmp (XSTR (SET_DEST (sub), 0), "predicable") == 0)
1423 sub = SET_SRC (sub);
1424 if (GET_CODE (sub) == CONST_STRING)
1426 predicable_idx = i;
1427 XSTR (sub, 0) = "ce_enabled";
1429 else
1430 /* We already give an error elsewhere. */
1431 return;
1432 break;
1434 if (strcmp (XSTR (SET_DEST (sub), 0), "enabled") == 0)
1436 enabled_idx = i;
1437 XSTR (SET_DEST (sub), 0) = "nonce_enabled";
1439 break;
1441 default:
1442 gcc_unreachable ();
1445 if (predicable_idx == -1)
1446 return;
1448 if (!global_changes_made)
1450 class queue_elem *elem;
1452 global_changes_made = true;
1453 add_define_attr ("ce_enabled");
1454 add_define_attr ("nonce_enabled");
1456 for (elem = define_attr_queue; elem ; elem = elem->next)
1457 if (strcmp (XSTR (elem->data, 0), "enabled") == 0)
1459 XEXP (elem->data, 2)
1460 = modify_attr_enabled_ce (XEXP (elem->data, 2));
1463 if (enabled_idx == -1)
1464 return;
1466 new_vec = rtvec_alloc (num_elem + 1);
1467 for (i = 0; i < num_elem; i++)
1468 RTVEC_ELT (new_vec, i) = RTVEC_ELT (vec, i);
1469 val = rtx_alloc (IF_THEN_ELSE);
1470 XEXP (val, 0) = rtx_alloc (EQ_ATTR);
1471 XEXP (val, 1) = rtx_alloc (CONST_STRING);
1472 XEXP (val, 2) = rtx_alloc (CONST_STRING);
1473 XSTR (XEXP (val, 0), 0) = "nonce_enabled";
1474 XSTR (XEXP (val, 0), 1) = "yes";
1475 XSTR (XEXP (val, 1), 0) = "yes";
1476 XSTR (XEXP (val, 2), 0) = "no";
1477 set = rtx_alloc (SET);
1478 SET_DEST (set) = rtx_alloc (ATTR);
1479 XSTR (SET_DEST (set), 0) = "enabled";
1480 SET_SRC (set) = modify_attr_enabled_ce (val);
1481 RTVEC_ELT (new_vec, i) = set;
1482 XVEC (insn, 4) = new_vec;
1485 /* As number of constraints is changed after define_subst, we need to
1486 process attributes as well - we need to duplicate them the same way
1487 that we duplicated constraints in original pattern
1488 ELEM is a queue element, containing our rtl-template,
1489 N_DUP - multiplication factor. */
1490 static void
1491 alter_attrs_for_subst_insn (class queue_elem * elem, int n_dup)
1493 rtvec vec = XVEC (elem->data, 4);
1494 int num_elem;
1495 int i;
1497 if (n_dup < 2 || ! vec)
1498 return;
1500 num_elem = GET_NUM_ELEM (vec);
1501 for (i = num_elem - 1; i >= 0; --i)
1503 rtx sub = RTVEC_ELT (vec, i);
1504 switch (GET_CODE (sub))
1506 case SET_ATTR:
1507 if (strchr (XSTR (sub, 1), ',') != NULL)
1508 XSTR (sub, 1) = duplicate_alternatives (XSTR (sub, 1), n_dup);
1509 break;
1511 case SET_ATTR_ALTERNATIVE:
1512 case SET:
1513 error_at (elem->loc,
1514 "%s: `define_subst' does not support attributes "
1515 "assigned by `set' and `set_attr_alternative'",
1516 XSTR (elem->data, 0));
1517 return;
1519 default:
1520 gcc_unreachable ();
1525 /* Adjust all of the operand numbers in SRC to match the shift they'll
1526 get from an operand displacement of DISP. Return a pointer after the
1527 adjusted string. */
1529 static char *
1530 shift_output_template (char *dest, const char *src, int disp)
1532 while (*src)
1534 char c = *src++;
1535 *dest++ = c;
1536 if (c == '%')
1538 c = *src++;
1539 if (ISDIGIT ((unsigned char) c))
1540 c += disp;
1541 else if (ISALPHA (c))
1543 *dest++ = c;
1544 c = *src++ + disp;
1546 *dest++ = c;
1550 return dest;
1553 static const char *
1554 alter_output_for_insn (class queue_elem *ce_elem,
1555 class queue_elem *insn_elem,
1556 int alt, int max_op)
1558 const char *ce_out, *insn_out;
1559 char *result, *p;
1560 size_t len, ce_len, insn_len;
1562 /* ??? Could coordinate with genoutput to not duplicate code here. */
1564 ce_out = XSTR (ce_elem->data, 2);
1565 insn_out = XTMPL (insn_elem->data, 3);
1566 if (!ce_out || *ce_out == '\0')
1567 return insn_out;
1569 ce_len = strlen (ce_out);
1570 insn_len = strlen (insn_out);
1572 if (*insn_out == '*')
1573 /* You must take care of the predicate yourself. */
1574 return insn_out;
1576 if (*insn_out == '@')
1578 len = (ce_len + 1) * alt + insn_len + 1;
1579 p = result = XNEWVEC (char, len);
1584 *p++ = *insn_out++;
1585 while (ISSPACE ((unsigned char) *insn_out));
1587 if (*insn_out != '#')
1589 p = shift_output_template (p, ce_out, max_op);
1590 *p++ = ' ';
1594 *p++ = *insn_out++;
1595 while (*insn_out && *insn_out != '\n');
1597 while (*insn_out);
1598 *p = '\0';
1600 else
1602 len = ce_len + 1 + insn_len + 1;
1603 result = XNEWVEC (char, len);
1605 p = shift_output_template (result, ce_out, max_op);
1606 *p++ = ' ';
1607 memcpy (p, insn_out, insn_len + 1);
1610 return result;
1613 /* From string STR "a,b,c" produce "a,b,c,a,b,c,a,b,c", i.e. original
1614 string, duplicated N_DUP times. */
1616 static const char *
1617 duplicate_alternatives (const char * str, int n_dup)
1619 int i, len, new_len;
1620 char *result, *sp;
1621 const char *cp;
1623 if (n_dup < 2)
1624 return str;
1626 while (ISSPACE (*str))
1627 str++;
1629 if (*str == '\0')
1630 return str;
1632 cp = str;
1633 len = strlen (str);
1634 new_len = (len + 1) * n_dup;
1636 sp = result = XNEWVEC (char, new_len);
1638 /* Global modifier characters mustn't be duplicated: skip if found. */
1639 if (*cp == '=' || *cp == '+' || *cp == '%')
1641 *sp++ = *cp++;
1642 len--;
1645 /* Copy original constraints N_DUP times. */
1646 for (i = 0; i < n_dup; i++, sp += len+1)
1648 memcpy (sp, cp, len);
1649 *(sp+len) = (i == n_dup - 1) ? '\0' : ',';
1652 return result;
1655 /* From string STR "a,b,c" produce "a,a,a,b,b,b,c,c,c", i.e. string where
1656 each alternative from the original string is duplicated N_DUP times. */
1657 static const char *
1658 duplicate_each_alternative (const char * str, int n_dup)
1660 int i, len, new_len;
1661 char *result, *sp, *ep, *cp;
1663 if (n_dup < 2)
1664 return str;
1666 while (ISSPACE (*str))
1667 str++;
1669 if (*str == '\0')
1670 return str;
1672 cp = xstrdup (str);
1674 new_len = (strlen (cp) + 1) * n_dup;
1676 sp = result = XNEWVEC (char, new_len);
1678 /* Global modifier characters mustn't be duplicated: skip if found. */
1679 if (*cp == '=' || *cp == '+' || *cp == '%')
1680 *sp++ = *cp++;
1684 if ((ep = strchr (cp, ',')) != NULL)
1685 *ep++ = '\0';
1686 len = strlen (cp);
1688 /* Copy a constraint N_DUP times. */
1689 for (i = 0; i < n_dup; i++, sp += len + 1)
1691 memcpy (sp, cp, len);
1692 *(sp+len) = (ep == NULL && i == n_dup - 1) ? '\0' : ',';
1695 cp = ep;
1697 while (cp != NULL);
1699 return result;
1702 /* Alter the output of INSN whose pattern was modified by
1703 DEFINE_SUBST. We must replicate output strings according
1704 to the new number of alternatives ALT in substituted pattern.
1705 If ALT equals 1, output has one alternative or defined by C
1706 code, then output is returned without any changes. */
1708 static const char *
1709 alter_output_for_subst_insn (rtx insn, int alt)
1711 const char *insn_out, *old_out;
1712 char *new_out, *cp;
1713 size_t old_len, new_len;
1714 int j;
1716 insn_out = XTMPL (insn, 3);
1718 if (alt < 2 || *insn_out != '@')
1719 return insn_out;
1721 old_out = insn_out + 1;
1722 while (ISSPACE (*old_out))
1723 old_out++;
1724 old_len = strlen (old_out);
1726 new_len = alt * (old_len + 1) + 1;
1728 new_out = XNEWVEC (char, new_len);
1729 new_out[0] = '@';
1731 for (j = 0, cp = new_out + 1; j < alt; j++, cp += old_len + 1)
1733 memcpy (cp, old_out, old_len);
1734 cp[old_len] = (j == alt - 1) ? '\0' : '\n';
1737 return new_out;
1740 /* Replicate insns as appropriate for the given DEFINE_COND_EXEC. */
1742 static void
1743 process_one_cond_exec (class queue_elem *ce_elem)
1745 class queue_elem *insn_elem;
1746 for (insn_elem = define_insn_queue; insn_elem ; insn_elem = insn_elem->next)
1748 int alternatives, max_operand;
1749 rtx pred, insn, pattern, split;
1750 char *new_name;
1751 int i;
1753 if (! is_predicable (insn_elem))
1754 continue;
1756 alternatives = 1;
1757 max_operand = -1;
1758 collect_insn_data (insn_elem->data, &alternatives, &max_operand);
1759 max_operand += 1;
1761 if (XVECLEN (ce_elem->data, 0) != 1)
1763 error_at (ce_elem->loc, "too many patterns in predicate");
1764 return;
1767 pred = copy_rtx (XVECEXP (ce_elem->data, 0, 0));
1768 pred = alter_predicate_for_insn (pred, alternatives, max_operand,
1769 ce_elem->loc);
1770 if (pred == NULL)
1771 return;
1773 /* Construct a new pattern for the new insn. */
1774 insn = copy_rtx (insn_elem->data);
1775 new_name = XNEWVAR (char, strlen XSTR (insn_elem->data, 0) + 4);
1776 sprintf (new_name, "*p %s", XSTR (insn_elem->data, 0));
1777 XSTR (insn, 0) = new_name;
1778 pattern = rtx_alloc (COND_EXEC);
1779 XEXP (pattern, 0) = pred;
1780 XEXP (pattern, 1) = add_implicit_parallel (XVEC (insn, 1));
1781 XVEC (insn, 1) = rtvec_alloc (1);
1782 XVECEXP (insn, 1, 0) = pattern;
1784 if (XVEC (ce_elem->data, 3) != NULL)
1786 rtvec attributes = rtvec_alloc (XVECLEN (insn, 4)
1787 + XVECLEN (ce_elem->data, 3));
1788 int i = 0;
1789 int j = 0;
1790 for (i = 0; i < XVECLEN (insn, 4); i++)
1791 RTVEC_ELT (attributes, i) = XVECEXP (insn, 4, i);
1793 for (j = 0; j < XVECLEN (ce_elem->data, 3); j++, i++)
1794 RTVEC_ELT (attributes, i) = XVECEXP (ce_elem->data, 3, j);
1796 XVEC (insn, 4) = attributes;
1799 XSTR (insn, 2) = alter_test_for_insn (ce_elem, insn_elem);
1800 XTMPL (insn, 3) = alter_output_for_insn (ce_elem, insn_elem,
1801 alternatives, max_operand);
1802 alter_attrs_for_insn (insn);
1804 /* Put the new pattern on the `other' list so that it
1805 (a) is not reprocessed by other define_cond_exec patterns
1806 (b) appears after all normal define_insn patterns.
1808 ??? B is debatable. If one has normal insns that match
1809 cond_exec patterns, they will be preferred over these
1810 generated patterns. Whether this matters in practice, or if
1811 it's a good thing, or whether we should thread these new
1812 patterns into the define_insn chain just after their generator
1813 is something we'll have to experiment with. */
1815 queue_pattern (insn, &other_tail, insn_elem->loc);
1817 if (!insn_elem->split)
1818 continue;
1820 /* If the original insn came from a define_insn_and_split,
1821 generate a new split to handle the predicated insn. */
1822 split = copy_rtx (insn_elem->split->data);
1823 /* Predicate the pattern matched by the split. */
1824 pattern = rtx_alloc (COND_EXEC);
1825 XEXP (pattern, 0) = pred;
1826 XEXP (pattern, 1) = add_implicit_parallel (XVEC (split, 0));
1827 XVEC (split, 0) = rtvec_alloc (1);
1828 XVECEXP (split, 0, 0) = pattern;
1830 /* Predicate all of the insns generated by the split. */
1831 for (i = 0; i < XVECLEN (split, 2); i++)
1833 pattern = rtx_alloc (COND_EXEC);
1834 XEXP (pattern, 0) = pred;
1835 XEXP (pattern, 1) = XVECEXP (split, 2, i);
1836 XVECEXP (split, 2, i) = pattern;
1838 /* Add the new split to the queue. */
1839 queue_pattern (split, &other_tail, insn_elem->split->loc);
1843 /* Try to apply define_substs to the given ELEM.
1844 Only define_substs, specified via attributes would be applied.
1845 If attribute, requiring define_subst, is set, but no define_subst
1846 was applied, ELEM would be deleted. */
1848 static void
1849 process_substs_on_one_elem (class queue_elem *elem,
1850 class queue_elem *queue)
1852 class queue_elem *subst_elem;
1853 int i, j, patterns_match;
1855 for (subst_elem = define_subst_queue;
1856 subst_elem; subst_elem = subst_elem->next)
1858 int alternatives, alternatives_subst;
1859 rtx subst_pattern;
1860 rtvec subst_pattern_vec;
1862 if (!has_subst_attribute (elem, subst_elem))
1863 continue;
1865 /* Compare original rtl-pattern from define_insn with input
1866 pattern from define_subst.
1867 Also, check if numbers of alternatives are the same in all
1868 match_operands. */
1869 if (XVECLEN (elem->data, 1) != XVECLEN (subst_elem->data, 1))
1870 continue;
1871 patterns_match = 1;
1872 alternatives = -1;
1873 alternatives_subst = -1;
1874 for (j = 0; j < XVECLEN (elem->data, 1); j++)
1876 if (!subst_pattern_match (XVECEXP (elem->data, 1, j),
1877 XVECEXP (subst_elem->data, 1, j),
1878 subst_elem->loc))
1880 patterns_match = 0;
1881 break;
1884 if (!get_alternatives_number (XVECEXP (elem->data, 1, j),
1885 &alternatives, subst_elem->loc))
1887 patterns_match = 0;
1888 break;
1892 /* Check if numbers of alternatives are the same in all
1893 match_operands in output template of define_subst. */
1894 for (j = 0; j < XVECLEN (subst_elem->data, 3); j++)
1896 if (!get_alternatives_number (XVECEXP (subst_elem->data, 3, j),
1897 &alternatives_subst,
1898 subst_elem->loc))
1900 patterns_match = 0;
1901 break;
1905 if (!patterns_match)
1906 continue;
1908 /* Clear array in which we save occupied indexes of operands. */
1909 memset (used_operands_numbers, 0, sizeof (used_operands_numbers));
1911 /* Create a pattern, based on the output one from define_subst. */
1912 subst_pattern_vec = rtvec_alloc (XVECLEN (subst_elem->data, 3));
1913 for (j = 0; j < XVECLEN (subst_elem->data, 3); j++)
1915 subst_pattern = copy_rtx (XVECEXP (subst_elem->data, 3, j));
1917 /* Duplicate constraints in substitute-pattern. */
1918 subst_pattern = alter_constraints (subst_pattern, alternatives,
1919 duplicate_each_alternative);
1921 subst_pattern = adjust_operands_numbers (subst_pattern);
1923 /* Substitute match_dup and match_op_dup in the new pattern and
1924 duplicate constraints. */
1925 subst_pattern = subst_dup (subst_pattern, alternatives,
1926 alternatives_subst);
1928 replace_duplicating_operands_in_pattern (subst_pattern);
1930 /* We don't need any constraints in DEFINE_EXPAND. */
1931 if (GET_CODE (elem->data) == DEFINE_EXPAND)
1932 remove_constraints (subst_pattern);
1934 RTVEC_ELT (subst_pattern_vec, j) = subst_pattern;
1936 XVEC (elem->data, 1) = subst_pattern_vec;
1938 for (i = 0; i < MAX_OPERANDS; i++)
1939 match_operand_entries_in_pattern[i] = NULL;
1941 if (GET_CODE (elem->data) == DEFINE_INSN)
1943 XTMPL (elem->data, 3) =
1944 alter_output_for_subst_insn (elem->data, alternatives_subst);
1945 alter_attrs_for_subst_insn (elem, alternatives_subst);
1948 /* Recalculate condition, joining conditions from original and
1949 DEFINE_SUBST input patterns. */
1950 XSTR (elem->data, 2)
1951 = rtx_reader_ptr->join_c_conditions (XSTR (subst_elem->data, 2),
1952 XSTR (elem->data, 2));
1953 /* Mark that subst was applied by changing attribute from "yes"
1954 to "no". */
1955 change_subst_attribute (elem, subst_elem, subst_false);
1958 /* If ELEM contains a subst attribute with value "yes", then we
1959 expected that a subst would be applied, but it wasn't - so,
1960 we need to remove that elementto avoid duplicating. */
1961 for (subst_elem = define_subst_queue;
1962 subst_elem; subst_elem = subst_elem->next)
1964 if (has_subst_attribute (elem, subst_elem))
1966 remove_from_queue (elem, &queue);
1967 return;
1972 /* This is a subroutine of mark_operands_used_in_match_dup.
1973 This routine is marks all MATCH_OPERANDs inside PATTERN as occupied. */
1974 static void
1975 mark_operands_from_match_dup (rtx pattern)
1977 const char *fmt;
1978 int i, j, len, opno;
1980 if (GET_CODE (pattern) == MATCH_OPERAND
1981 || GET_CODE (pattern) == MATCH_OPERATOR
1982 || GET_CODE (pattern) == MATCH_PARALLEL)
1984 opno = XINT (pattern, 0);
1985 gcc_assert (opno >= 0 && opno < MAX_OPERANDS);
1986 used_operands_numbers [opno] = 1;
1988 fmt = GET_RTX_FORMAT (GET_CODE (pattern));
1989 len = GET_RTX_LENGTH (GET_CODE (pattern));
1990 for (i = 0; i < len; i++)
1992 switch (fmt[i])
1994 case 'e': case 'u':
1995 mark_operands_from_match_dup (XEXP (pattern, i));
1996 break;
1997 case 'E':
1998 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
1999 mark_operands_from_match_dup (XVECEXP (pattern, i, j));
2000 break;
2005 /* This is a subroutine of adjust_operands_numbers.
2006 It goes through all expressions in PATTERN and when MATCH_DUP is
2007 met, all MATCH_OPERANDs inside it is marked as occupied. The
2008 process of marking is done by routin mark_operands_from_match_dup. */
2009 static void
2010 mark_operands_used_in_match_dup (rtx pattern)
2012 const char *fmt;
2013 int i, j, len, opno;
2015 if (GET_CODE (pattern) == MATCH_DUP)
2017 opno = XINT (pattern, 0);
2018 gcc_assert (opno >= 0 && opno < MAX_OPERANDS);
2019 mark_operands_from_match_dup (operand_data[opno]);
2020 return;
2022 fmt = GET_RTX_FORMAT (GET_CODE (pattern));
2023 len = GET_RTX_LENGTH (GET_CODE (pattern));
2024 for (i = 0; i < len; i++)
2026 switch (fmt[i])
2028 case 'e': case 'u':
2029 mark_operands_used_in_match_dup (XEXP (pattern, i));
2030 break;
2031 case 'E':
2032 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
2033 mark_operands_used_in_match_dup (XVECEXP (pattern, i, j));
2034 break;
2039 /* This is subroutine of renumerate_operands_in_pattern.
2040 It finds first not-occupied operand-index. */
2041 static int
2042 find_first_unused_number_of_operand ()
2044 int i;
2045 for (i = 0; i < MAX_OPERANDS; i++)
2046 if (!used_operands_numbers[i])
2047 return i;
2048 return MAX_OPERANDS;
2051 /* This is subroutine of adjust_operands_numbers.
2052 It visits all expressions in PATTERN and assigns not-occupied
2053 operand indexes to MATCH_OPERANDs and MATCH_OPERATORs of this
2054 PATTERN. */
2055 static void
2056 renumerate_operands_in_pattern (rtx pattern)
2058 const char *fmt;
2059 enum rtx_code code;
2060 int i, j, len, new_opno;
2061 code = GET_CODE (pattern);
2063 if (code == MATCH_OPERAND
2064 || code == MATCH_OPERATOR)
2066 new_opno = find_first_unused_number_of_operand ();
2067 gcc_assert (new_opno >= 0 && new_opno < MAX_OPERANDS);
2068 XINT (pattern, 0) = new_opno;
2069 used_operands_numbers [new_opno] = 1;
2072 fmt = GET_RTX_FORMAT (GET_CODE (pattern));
2073 len = GET_RTX_LENGTH (GET_CODE (pattern));
2074 for (i = 0; i < len; i++)
2076 switch (fmt[i])
2078 case 'e': case 'u':
2079 renumerate_operands_in_pattern (XEXP (pattern, i));
2080 break;
2081 case 'E':
2082 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
2083 renumerate_operands_in_pattern (XVECEXP (pattern, i, j));
2084 break;
2089 /* If output pattern of define_subst contains MATCH_DUP, then this
2090 expression would be replaced with the pattern, matched with
2091 MATCH_OPERAND from input pattern. This pattern could contain any
2092 number of MATCH_OPERANDs, MATCH_OPERATORs etc., so it's possible
2093 that a MATCH_OPERAND from output_pattern (if any) would have the
2094 same number, as MATCH_OPERAND from copied pattern. To avoid such
2095 indexes overlapping, we assign new indexes to MATCH_OPERANDs,
2096 laying in the output pattern outside of MATCH_DUPs. */
2097 static rtx
2098 adjust_operands_numbers (rtx pattern)
2100 mark_operands_used_in_match_dup (pattern);
2102 renumerate_operands_in_pattern (pattern);
2104 return pattern;
2107 /* Generate RTL expression
2108 (match_dup OPNO)
2110 static rtx
2111 generate_match_dup (int opno)
2113 rtx return_rtx = rtx_alloc (MATCH_DUP);
2114 PUT_CODE (return_rtx, MATCH_DUP);
2115 XINT (return_rtx, 0) = opno;
2116 return return_rtx;
2119 /* This routine checks all match_operands in PATTERN and if some of
2120 have the same index, it replaces all of them except the first one to
2121 match_dup.
2122 Usually, match_operands with the same indexes are forbidden, but
2123 after define_subst copy an RTL-expression from original template,
2124 indexes of existed and just-copied match_operands could coincide.
2125 To fix it, we replace one of them with match_dup. */
2126 static rtx
2127 replace_duplicating_operands_in_pattern (rtx pattern)
2129 const char *fmt;
2130 int i, j, len, opno;
2131 rtx mdup;
2133 if (GET_CODE (pattern) == MATCH_OPERAND)
2135 opno = XINT (pattern, 0);
2136 gcc_assert (opno >= 0 && opno < MAX_OPERANDS);
2137 if (match_operand_entries_in_pattern[opno] == NULL)
2139 match_operand_entries_in_pattern[opno] = pattern;
2140 return NULL;
2142 else
2144 /* Compare predicates before replacing with match_dup. */
2145 if (strcmp (XSTR (pattern, 1),
2146 XSTR (match_operand_entries_in_pattern[opno], 1)))
2148 error ("duplicated match_operands with different predicates were"
2149 " found.");
2150 return NULL;
2152 return generate_match_dup (opno);
2155 fmt = GET_RTX_FORMAT (GET_CODE (pattern));
2156 len = GET_RTX_LENGTH (GET_CODE (pattern));
2157 for (i = 0; i < len; i++)
2159 switch (fmt[i])
2161 case 'e': case 'u':
2162 mdup = replace_duplicating_operands_in_pattern (XEXP (pattern, i));
2163 if (mdup)
2164 XEXP (pattern, i) = mdup;
2165 break;
2166 case 'E':
2167 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
2169 mdup =
2170 replace_duplicating_operands_in_pattern (XVECEXP
2171 (pattern, i, j));
2172 if (mdup)
2173 XVECEXP (pattern, i, j) = mdup;
2175 break;
2178 return NULL;
2181 /* The routine modifies given input PATTERN of define_subst, replacing
2182 MATCH_DUP and MATCH_OP_DUP with operands from define_insn original
2183 pattern, whose operands are stored in OPERAND_DATA array.
2184 It also duplicates constraints in operands - constraints from
2185 define_insn operands are duplicated N_SUBST_ALT times, constraints
2186 from define_subst operands are duplicated N_ALT times.
2187 After the duplication, returned output rtl-pattern contains every
2188 combination of input constraints Vs constraints from define_subst
2189 output. */
2190 static rtx
2191 subst_dup (rtx pattern, int n_alt, int n_subst_alt)
2193 const char *fmt;
2194 enum rtx_code code;
2195 int i, j, len, opno;
2197 code = GET_CODE (pattern);
2198 switch (code)
2200 case MATCH_DUP:
2201 case MATCH_OP_DUP:
2202 opno = XINT (pattern, 0);
2204 gcc_assert (opno >= 0 && opno < MAX_OPERANDS);
2206 if (operand_data[opno])
2208 pattern = copy_rtx (operand_data[opno]);
2210 /* Duplicate constraints. */
2211 pattern = alter_constraints (pattern, n_subst_alt,
2212 duplicate_alternatives);
2214 break;
2216 default:
2217 break;
2220 fmt = GET_RTX_FORMAT (GET_CODE (pattern));
2221 len = GET_RTX_LENGTH (GET_CODE (pattern));
2222 for (i = 0; i < len; i++)
2224 switch (fmt[i])
2226 case 'e': case 'u':
2227 if (code != MATCH_DUP && code != MATCH_OP_DUP)
2228 XEXP (pattern, i) = subst_dup (XEXP (pattern, i),
2229 n_alt, n_subst_alt);
2230 break;
2231 case 'V':
2232 if (XVEC (pattern, i) == NULL)
2233 break;
2234 /* FALLTHRU */
2235 case 'E':
2236 if (code != MATCH_DUP && code != MATCH_OP_DUP)
2237 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
2238 XVECEXP (pattern, i, j) = subst_dup (XVECEXP (pattern, i, j),
2239 n_alt, n_subst_alt);
2240 break;
2242 case 'r': case 'p': case 'i': case 'w':
2243 case '0': case 's': case 'S': case 'T':
2244 break;
2246 default:
2247 gcc_unreachable ();
2250 return pattern;
2253 /* If we have any DEFINE_COND_EXEC patterns, expand the DEFINE_INSN
2254 patterns appropriately. */
2256 static void
2257 process_define_cond_exec (void)
2259 class queue_elem *elem;
2261 identify_predicable_attribute ();
2262 if (have_error)
2263 return;
2265 for (elem = define_cond_exec_queue; elem ; elem = elem->next)
2266 process_one_cond_exec (elem);
2269 /* If we have any DEFINE_SUBST patterns, expand DEFINE_INSN and
2270 DEFINE_EXPAND patterns appropriately. */
2272 static void
2273 process_define_subst (void)
2275 class queue_elem *elem, *elem_attr;
2277 /* Check if each define_subst has corresponding define_subst_attr. */
2278 for (elem = define_subst_queue; elem ; elem = elem->next)
2280 for (elem_attr = define_subst_attr_queue;
2281 elem_attr;
2282 elem_attr = elem_attr->next)
2283 if (strcmp (XSTR (elem->data, 0), XSTR (elem_attr->data, 1)) == 0)
2284 goto found;
2286 error_at (elem->loc,
2287 "%s: `define_subst' must have at least one "
2288 "corresponding `define_subst_attr'",
2289 XSTR (elem->data, 0));
2290 return;
2292 found:
2293 continue;
2296 for (elem = define_insn_queue; elem ; elem = elem->next)
2297 process_substs_on_one_elem (elem, define_insn_queue);
2298 for (elem = other_queue; elem ; elem = elem->next)
2300 if (GET_CODE (elem->data) != DEFINE_EXPAND)
2301 continue;
2302 process_substs_on_one_elem (elem, other_queue);
2306 /* A subclass of rtx_reader which reads .md files and calls process_rtx on
2307 the top-level elements. */
2309 class gen_reader : public rtx_reader
2311 public:
2312 gen_reader () : rtx_reader (false) {}
2313 void handle_unknown_directive (file_location, const char *) final override;
2316 void
2317 gen_reader::handle_unknown_directive (file_location loc, const char *rtx_name)
2319 auto_vec<rtx, 32> subrtxs;
2320 if (!read_rtx (rtx_name, &subrtxs))
2321 return;
2323 rtx x;
2324 unsigned int i;
2325 FOR_EACH_VEC_ELT (subrtxs, i, x)
2326 process_rtx (x, loc);
2329 /* Add mnemonic STR with length LEN to the mnemonic hash table
2330 MNEMONIC_HTAB. A trailing zero end character is appended to STR
2331 and a permanent heap copy of STR is created. */
2333 static void
2334 add_mnemonic_string (htab_t mnemonic_htab, const char *str, size_t len)
2336 char *new_str;
2337 void **slot;
2338 char *str_zero = (char*)alloca (len + 1);
2340 memcpy (str_zero, str, len);
2341 str_zero[len] = '\0';
2343 slot = htab_find_slot (mnemonic_htab, str_zero, INSERT);
2345 if (*slot)
2346 return;
2348 /* Not found; create a permanent copy and add it to the hash table. */
2349 new_str = XNEWVAR (char, len + 1);
2350 memcpy (new_str, str_zero, len + 1);
2351 *slot = new_str;
2354 /* Scan INSN for mnemonic strings and add them to the mnemonic hash
2355 table in MNEMONIC_HTAB.
2357 The mnemonics cannot be found if they are emitted using C code.
2359 If a mnemonic string contains ';' or a newline the string assumed
2360 to consist of more than a single instruction. The attribute value
2361 will then be set to the user defined default value. */
2363 static void
2364 gen_mnemonic_setattr (htab_t mnemonic_htab, rtx insn)
2366 const char *template_code, *cp;
2367 int i;
2368 int vec_len;
2369 rtx set_attr;
2370 char *attr_name;
2371 rtvec new_vec;
2372 struct obstack *string_obstack = rtx_reader_ptr->get_string_obstack ();
2374 template_code = XTMPL (insn, 3);
2376 /* Skip patterns which use C code to emit the template. */
2377 if (template_code[0] == '*')
2378 return;
2380 if (template_code[0] == '@')
2381 cp = &template_code[1];
2382 else
2383 cp = &template_code[0];
2385 for (i = 0; *cp; )
2387 const char *ep, *sp;
2388 size_t size = 0;
2390 while (ISSPACE (*cp))
2391 cp++;
2393 for (ep = sp = cp; !IS_VSPACE (*ep) && *ep != '\0'; ++ep)
2394 if (!ISSPACE (*ep))
2395 sp = ep + 1;
2397 if (i > 0)
2398 obstack_1grow (string_obstack, ',');
2400 while (cp < sp && ((*cp >= '0' && *cp <= '9')
2401 || (*cp >= 'a' && *cp <= 'z')))
2404 obstack_1grow (string_obstack, *cp);
2405 cp++;
2406 size++;
2409 while (cp < sp)
2411 if (*cp == ';' || (*cp == '\\' && cp[1] == 'n'))
2413 /* Don't set a value if there are more than one
2414 instruction in the string. */
2415 obstack_blank_fast (string_obstack, -size);
2416 size = 0;
2418 cp = sp;
2419 break;
2421 cp++;
2423 if (size == 0)
2424 obstack_1grow (string_obstack, '*');
2425 else
2426 add_mnemonic_string (mnemonic_htab,
2427 (char *) obstack_next_free (string_obstack) - size,
2428 size);
2429 i++;
2432 /* An insn definition might emit an empty string. */
2433 if (obstack_object_size (string_obstack) == 0)
2434 return;
2436 obstack_1grow (string_obstack, '\0');
2438 set_attr = rtx_alloc (SET_ATTR);
2439 XSTR (set_attr, 1) = XOBFINISH (string_obstack, char *);
2440 attr_name = XNEWVAR (char, strlen (MNEMONIC_ATTR_NAME) + 1);
2441 strcpy (attr_name, MNEMONIC_ATTR_NAME);
2442 XSTR (set_attr, 0) = attr_name;
2444 if (!XVEC (insn, 4))
2445 vec_len = 0;
2446 else
2447 vec_len = XVECLEN (insn, 4);
2449 new_vec = rtvec_alloc (vec_len + 1);
2450 for (i = 0; i < vec_len; i++)
2451 RTVEC_ELT (new_vec, i) = XVECEXP (insn, 4, i);
2452 RTVEC_ELT (new_vec, vec_len) = set_attr;
2453 XVEC (insn, 4) = new_vec;
2456 /* This function is called for the elements in the mnemonic hashtable
2457 and generates a comma separated list of the mnemonics. */
2459 static int
2460 mnemonic_htab_callback (void **slot, void *info ATTRIBUTE_UNUSED)
2462 struct obstack *string_obstack = rtx_reader_ptr->get_string_obstack ();
2464 obstack_grow (string_obstack, (char*) *slot, strlen ((char*) *slot));
2465 obstack_1grow (string_obstack, ',');
2466 return 1;
2469 /* Generate (set_attr "mnemonic" "..") RTXs and append them to every
2470 insn definition in case the back end requests it by defining the
2471 mnemonic attribute. The values for the attribute will be extracted
2472 from the output patterns of the insn definitions as far as
2473 possible. */
2475 static void
2476 gen_mnemonic_attr (void)
2478 class queue_elem *elem;
2479 rtx mnemonic_attr = NULL;
2480 htab_t mnemonic_htab;
2481 const char *str, *p;
2482 int i;
2483 struct obstack *string_obstack = rtx_reader_ptr->get_string_obstack ();
2485 if (have_error)
2486 return;
2488 /* Look for the DEFINE_ATTR for `mnemonic'. */
2489 for (elem = define_attr_queue; elem != *define_attr_tail; elem = elem->next)
2490 if (GET_CODE (elem->data) == DEFINE_ATTR
2491 && strcmp (XSTR (elem->data, 0), MNEMONIC_ATTR_NAME) == 0)
2493 mnemonic_attr = elem->data;
2494 break;
2497 /* A (define_attr "mnemonic" "...") indicates that the back-end
2498 wants a mnemonic attribute to be generated. */
2499 if (!mnemonic_attr)
2500 return;
2502 mnemonic_htab = htab_create_alloc (MNEMONIC_HTAB_SIZE, htab_hash_string,
2503 htab_eq_string, 0, xcalloc, free);
2505 for (elem = define_insn_queue; elem; elem = elem->next)
2507 rtx insn = elem->data;
2508 bool found = false;
2510 /* Check if the insn definition already has
2511 (set_attr "mnemonic" ...) or (set (attr "mnemonic") ...). */
2512 if (XVEC (insn, 4))
2513 for (i = 0; i < XVECLEN (insn, 4); i++)
2515 rtx set_attr = XVECEXP (insn, 4, i);
2517 switch (GET_CODE (set_attr))
2519 case SET_ATTR:
2520 case SET_ATTR_ALTERNATIVE:
2521 if (strcmp (XSTR (set_attr, 0), MNEMONIC_ATTR_NAME) == 0)
2522 found = true;
2523 break;
2524 case SET:
2525 if (GET_CODE (SET_DEST (set_attr)) == ATTR
2526 && strcmp (XSTR (SET_DEST (set_attr), 0),
2527 MNEMONIC_ATTR_NAME) == 0)
2528 found = true;
2529 break;
2530 default:
2531 break;
2535 if (!found)
2536 gen_mnemonic_setattr (mnemonic_htab, insn);
2539 /* Add the user defined values to the hash table. */
2540 str = XSTR (mnemonic_attr, 1);
2541 while ((p = scan_comma_elt (&str)) != NULL)
2542 add_mnemonic_string (mnemonic_htab, p, str - p);
2544 htab_traverse (mnemonic_htab, mnemonic_htab_callback, NULL);
2546 /* Replace the last ',' with the zero end character. */
2547 *((char *) obstack_next_free (string_obstack) - 1) = '\0';
2548 XSTR (mnemonic_attr, 1) = XOBFINISH (string_obstack, char *);
2551 /* Check if there are DEFINE_ATTRs with the same name. */
2552 static void
2553 check_define_attr_duplicates ()
2555 class queue_elem *elem;
2556 htab_t attr_htab;
2557 char * attr_name;
2558 void **slot;
2560 attr_htab = htab_create (500, htab_hash_string, htab_eq_string, NULL);
2562 for (elem = define_attr_queue; elem; elem = elem->next)
2564 attr_name = xstrdup (XSTR (elem->data, 0));
2566 slot = htab_find_slot (attr_htab, attr_name, INSERT);
2568 /* Duplicate. */
2569 if (*slot)
2571 error_at (elem->loc, "redefinition of attribute '%s'", attr_name);
2572 htab_delete (attr_htab);
2573 return;
2576 *slot = attr_name;
2579 htab_delete (attr_htab);
2582 /* The entry point for initializing the reader. */
2584 rtx_reader *
2585 init_rtx_reader_args_cb (int argc, const char **argv,
2586 bool (*parse_opt) (const char *))
2588 /* Prepare to read input. */
2589 condition_table = htab_create (500, hash_c_test, cmp_c_test, NULL);
2590 init_predicate_table ();
2591 obstack_init (rtl_obstack);
2593 /* Start at 1, to make 0 available for CODE_FOR_nothing. */
2594 insn_sequence_num = 1;
2596 /* These sequences are not used as indices, so can start at 1 also. */
2597 split_sequence_num = 1;
2598 peephole2_sequence_num = 1;
2600 gen_reader *reader = new gen_reader ();
2601 reader->read_md_files (argc, argv, parse_opt);
2603 if (define_attr_queue != NULL)
2604 check_define_attr_duplicates ();
2606 /* Process define_cond_exec patterns. */
2607 if (define_cond_exec_queue != NULL)
2608 process_define_cond_exec ();
2610 /* Process define_subst patterns. */
2611 if (define_subst_queue != NULL)
2612 process_define_subst ();
2614 if (define_attr_queue != NULL)
2615 gen_mnemonic_attr ();
2617 if (have_error)
2619 delete reader;
2620 return NULL;
2623 return reader;
2626 /* Programs that don't have their own options can use this entry point
2627 instead. */
2628 rtx_reader *
2629 init_rtx_reader_args (int argc, const char **argv)
2631 return init_rtx_reader_args_cb (argc, argv, 0);
2634 /* Try to read a single rtx from the file. Return true on success,
2635 describing it in *INFO. */
2637 bool
2638 read_md_rtx (md_rtx_info *info)
2640 int truth, *counter;
2641 rtx def;
2643 /* Discard insn patterns which we know can never match (because
2644 their C test is provably always false). If insn_elision is
2645 false, our caller needs to see all the patterns. Note that the
2646 elided patterns are never counted by the sequence numbering; it
2647 is the caller's responsibility, when insn_elision is false, not
2648 to use elided pattern numbers for anything. */
2651 class queue_elem **queue, *elem;
2653 /* Read all patterns from a given queue before moving on to the next. */
2654 if (define_attr_queue != NULL)
2655 queue = &define_attr_queue;
2656 else if (define_pred_queue != NULL)
2657 queue = &define_pred_queue;
2658 else if (define_insn_queue != NULL)
2659 queue = &define_insn_queue;
2660 else if (other_queue != NULL)
2661 queue = &other_queue;
2662 else
2663 return false;
2665 elem = *queue;
2666 *queue = elem->next;
2667 def = elem->data;
2668 info->def = def;
2669 info->loc = elem->loc;
2670 free (elem);
2672 truth = maybe_eval_c_test (get_c_test (def));
2674 while (truth == 0 && insn_elision);
2676 /* Perform code-specific processing and pick the appropriate sequence
2677 number counter. */
2678 switch (GET_CODE (def))
2680 case DEFINE_INSN:
2681 case DEFINE_EXPAND:
2682 /* insn_sequence_num is used here so the name table will match caller's
2683 idea of insn numbering, whether or not elision is active. */
2684 record_insn_name (insn_sequence_num, XSTR (def, 0));
2686 /* Fall through. */
2687 case DEFINE_PEEPHOLE:
2688 counter = &insn_sequence_num;
2689 break;
2691 case DEFINE_SPLIT:
2692 counter = &split_sequence_num;
2693 break;
2695 case DEFINE_PEEPHOLE2:
2696 counter = &peephole2_sequence_num;
2697 break;
2699 default:
2700 counter = NULL;
2701 break;
2704 if (counter)
2706 info->index = *counter;
2707 if (truth != 0)
2708 *counter += 1;
2710 else
2711 info->index = -1;
2713 if (!rtx_locs)
2714 rtx_locs = new hash_map <rtx, file_location>;
2715 rtx_locs->put (info->def, info->loc);
2717 return true;
2720 /* Return the file location of DEFINE_* rtx X, which was previously
2721 returned by read_md_rtx. */
2722 file_location
2723 get_file_location (rtx x)
2725 gcc_assert (rtx_locs);
2726 file_location *entry = rtx_locs->get (x);
2727 gcc_assert (entry);
2728 return *entry;
2731 /* Return the number of possible INSN_CODEs. Only meaningful once the
2732 whole file has been processed. */
2733 unsigned int
2734 get_num_insn_codes ()
2736 return insn_sequence_num;
2739 /* Return the C test that says whether definition rtx DEF can be used,
2740 or "" if it can be used unconditionally. */
2742 const char *
2743 get_c_test (rtx x)
2745 switch (GET_CODE (x))
2747 case DEFINE_INSN:
2748 case DEFINE_EXPAND:
2749 case DEFINE_SUBST:
2750 return XSTR (x, 2);
2752 case DEFINE_SPLIT:
2753 case DEFINE_PEEPHOLE:
2754 case DEFINE_PEEPHOLE2:
2755 return XSTR (x, 1);
2757 default:
2758 return "";
2762 /* Helper functions for insn elision. */
2764 /* Compute a hash function of a c_test structure, which is keyed
2765 by its ->expr field. */
2766 hashval_t
2767 hash_c_test (const void *x)
2769 const struct c_test *a = (const struct c_test *) x;
2770 const unsigned char *base, *s = (const unsigned char *) a->expr;
2771 hashval_t hash;
2772 unsigned char c;
2773 unsigned int len;
2775 base = s;
2776 hash = 0;
2778 while ((c = *s++) != '\0')
2780 hash += c + (c << 17);
2781 hash ^= hash >> 2;
2784 len = s - base;
2785 hash += len + (len << 17);
2786 hash ^= hash >> 2;
2788 return hash;
2791 /* Compare two c_test expression structures. */
2793 cmp_c_test (const void *x, const void *y)
2795 const struct c_test *a = (const struct c_test *) x;
2796 const struct c_test *b = (const struct c_test *) y;
2798 return !strcmp (a->expr, b->expr);
2801 /* Given a string representing a C test expression, look it up in the
2802 condition_table and report whether or not its value is known
2803 at compile time. Returns a tristate: 1 for known true, 0 for
2804 known false, -1 for unknown. */
2806 maybe_eval_c_test (const char *expr)
2808 const struct c_test *test;
2809 struct c_test dummy;
2811 if (expr[0] == 0)
2812 return 1;
2814 dummy.expr = expr;
2815 test = (const struct c_test *)htab_find (condition_table, &dummy);
2816 if (!test)
2817 return -1;
2818 return test->value;
2821 /* Record the C test expression EXPR in the condition_table, with
2822 value VAL. Duplicates clobber previous entries. */
2824 void
2825 add_c_test (const char *expr, int value)
2827 struct c_test *test;
2829 if (expr[0] == 0)
2830 return;
2832 test = XNEW (struct c_test);
2833 test->expr = expr;
2834 test->value = value;
2836 *(htab_find_slot (condition_table, test, INSERT)) = test;
2839 /* For every C test, call CALLBACK with two arguments: a pointer to
2840 the condition structure and INFO. Stops when CALLBACK returns zero. */
2841 void
2842 traverse_c_tests (htab_trav callback, void *info)
2844 if (condition_table)
2845 htab_traverse (condition_table, callback, info);
2848 /* Helper functions for define_predicate and define_special_predicate
2849 processing. Shared between genrecog.cc and genpreds.cc. */
2851 static htab_t predicate_table;
2852 struct pred_data *first_predicate;
2853 static struct pred_data **last_predicate = &first_predicate;
2855 static hashval_t
2856 hash_struct_pred_data (const void *ptr)
2858 return htab_hash_string (((const struct pred_data *)ptr)->name);
2861 static int
2862 eq_struct_pred_data (const void *a, const void *b)
2864 return !strcmp (((const struct pred_data *)a)->name,
2865 ((const struct pred_data *)b)->name);
2868 struct pred_data *
2869 lookup_predicate (const char *name)
2871 struct pred_data key;
2872 key.name = name;
2873 return (struct pred_data *) htab_find (predicate_table, &key);
2876 /* Record that predicate PRED can accept CODE. */
2878 void
2879 add_predicate_code (struct pred_data *pred, enum rtx_code code)
2881 if (!pred->codes[code])
2883 pred->num_codes++;
2884 pred->codes[code] = true;
2886 if (GET_RTX_CLASS (code) != RTX_CONST_OBJ)
2887 pred->allows_non_const = true;
2889 if (code != REG
2890 && code != SUBREG
2891 && code != MEM
2892 && code != CONCAT
2893 && code != PARALLEL
2894 && code != STRICT_LOW_PART
2895 && code != ZERO_EXTRACT
2896 && code != SCRATCH)
2897 pred->allows_non_lvalue = true;
2899 if (pred->num_codes == 1)
2900 pred->singleton = code;
2901 else if (pred->num_codes == 2)
2902 pred->singleton = UNKNOWN;
2906 void
2907 add_predicate (struct pred_data *pred)
2909 void **slot = htab_find_slot (predicate_table, pred, INSERT);
2910 if (*slot)
2912 error ("duplicate predicate definition for '%s'", pred->name);
2913 return;
2915 *slot = pred;
2916 *last_predicate = pred;
2917 last_predicate = &pred->next;
2920 /* This array gives the initial content of the predicate table. It
2921 has entries for all predicates defined in recog.cc. */
2923 struct std_pred_table
2925 const char *name;
2926 bool special;
2927 bool allows_const_p;
2928 RTX_CODE codes[NUM_RTX_CODE];
2931 static const struct std_pred_table std_preds[] = {
2932 {"general_operand", false, true, {SUBREG, REG, MEM}},
2933 {"address_operand", true, true, {SUBREG, REG, MEM, PLUS, MINUS, MULT,
2934 ZERO_EXTEND, SIGN_EXTEND, AND}},
2935 {"register_operand", false, false, {SUBREG, REG}},
2936 {"pmode_register_operand", true, false, {SUBREG, REG}},
2937 {"scratch_operand", false, false, {SCRATCH, REG}},
2938 {"immediate_operand", false, true, {UNKNOWN}},
2939 {"const_int_operand", false, false, {CONST_INT}},
2940 #if TARGET_SUPPORTS_WIDE_INT
2941 {"const_scalar_int_operand", false, false, {CONST_INT, CONST_WIDE_INT}},
2942 {"const_double_operand", false, false, {CONST_DOUBLE}},
2943 #else
2944 {"const_double_operand", false, false, {CONST_INT, CONST_DOUBLE}},
2945 #endif
2946 {"nonimmediate_operand", false, false, {SUBREG, REG, MEM}},
2947 {"nonmemory_operand", false, true, {SUBREG, REG}},
2948 {"push_operand", false, false, {MEM}},
2949 {"pop_operand", false, false, {MEM}},
2950 {"memory_operand", false, false, {SUBREG, MEM}},
2951 {"indirect_operand", false, false, {SUBREG, MEM}},
2952 {"ordered_comparison_operator", false, false, {EQ, NE,
2953 LE, LT, GE, GT,
2954 LEU, LTU, GEU, GTU}},
2955 {"comparison_operator", false, false, {EQ, NE,
2956 LE, LT, GE, GT,
2957 LEU, LTU, GEU, GTU,
2958 UNORDERED, ORDERED,
2959 UNEQ, UNGE, UNGT,
2960 UNLE, UNLT, LTGT}}
2962 #define NUM_KNOWN_STD_PREDS ARRAY_SIZE (std_preds)
2964 /* Initialize the table of predicate definitions, starting with
2965 the information we have on generic predicates. */
2967 static void
2968 init_predicate_table (void)
2970 size_t i, j;
2971 struct pred_data *pred;
2973 predicate_table = htab_create_alloc (37, hash_struct_pred_data,
2974 eq_struct_pred_data, 0,
2975 xcalloc, free);
2977 for (i = 0; i < NUM_KNOWN_STD_PREDS; i++)
2979 pred = XCNEW (struct pred_data);
2980 pred->name = std_preds[i].name;
2981 pred->special = std_preds[i].special;
2983 for (j = 0; std_preds[i].codes[j] != 0; j++)
2984 add_predicate_code (pred, std_preds[i].codes[j]);
2986 if (std_preds[i].allows_const_p)
2987 for (j = 0; j < NUM_RTX_CODE; j++)
2988 if (GET_RTX_CLASS (j) == RTX_CONST_OBJ)
2989 add_predicate_code (pred, (enum rtx_code) j);
2991 add_predicate (pred);
2995 /* These functions allow linkage with print-rtl.cc. Also, some generators
2996 like to annotate their output with insn names. */
2998 /* Holds an array of names indexed by insn_code_number. */
2999 static char **insn_name_ptr = 0;
3000 static int insn_name_ptr_size = 0;
3002 const char *
3003 get_insn_name (int code)
3005 if (code < insn_name_ptr_size)
3006 return insn_name_ptr[code];
3007 else
3008 return NULL;
3011 static void
3012 record_insn_name (int code, const char *name)
3014 static const char *last_real_name = "insn";
3015 static int last_real_code = 0;
3016 char *new_name;
3018 if (insn_name_ptr_size <= code)
3020 int new_size;
3021 new_size = (insn_name_ptr_size ? insn_name_ptr_size * 2 : 512);
3022 insn_name_ptr = XRESIZEVEC (char *, insn_name_ptr, new_size);
3023 memset (insn_name_ptr + insn_name_ptr_size, 0,
3024 sizeof (char *) * (new_size - insn_name_ptr_size));
3025 insn_name_ptr_size = new_size;
3028 if (!name || name[0] == '\0')
3030 new_name = XNEWVAR (char, strlen (last_real_name) + 10);
3031 sprintf (new_name, "%s+%d", last_real_name, code - last_real_code);
3033 else
3035 last_real_name = new_name = xstrdup (name);
3036 last_real_code = code;
3039 insn_name_ptr[code] = new_name;
3042 /* Make STATS describe the operands that appear in rtx X. */
3044 static void
3045 get_pattern_stats_1 (struct pattern_stats *stats, rtx x)
3047 RTX_CODE code;
3048 int i;
3049 int len;
3050 const char *fmt;
3052 if (x == NULL_RTX)
3053 return;
3055 code = GET_CODE (x);
3056 switch (code)
3058 case MATCH_OPERAND:
3059 case MATCH_OPERATOR:
3060 case MATCH_PARALLEL:
3061 stats->max_opno = MAX (stats->max_opno, XINT (x, 0));
3062 break;
3064 case MATCH_DUP:
3065 case MATCH_OP_DUP:
3066 case MATCH_PAR_DUP:
3067 stats->num_dups++;
3068 stats->max_dup_opno = MAX (stats->max_dup_opno, XINT (x, 0));
3069 break;
3071 case MATCH_SCRATCH:
3072 if (stats->min_scratch_opno == -1)
3073 stats->min_scratch_opno = XINT (x, 0);
3074 else
3075 stats->min_scratch_opno = MIN (stats->min_scratch_opno, XINT (x, 0));
3076 stats->max_scratch_opno = MAX (stats->max_scratch_opno, XINT (x, 0));
3077 break;
3079 default:
3080 break;
3083 fmt = GET_RTX_FORMAT (code);
3084 len = GET_RTX_LENGTH (code);
3085 for (i = 0; i < len; i++)
3087 if (fmt[i] == 'e' || fmt[i] == 'u')
3088 get_pattern_stats_1 (stats, XEXP (x, i));
3089 else if (fmt[i] == 'E')
3091 int j;
3092 for (j = 0; j < XVECLEN (x, i); j++)
3093 get_pattern_stats_1 (stats, XVECEXP (x, i, j));
3098 /* Make STATS describe the operands that appear in instruction pattern
3099 PATTERN. */
3101 void
3102 get_pattern_stats (struct pattern_stats *stats, rtvec pattern)
3104 int i, len;
3106 stats->max_opno = -1;
3107 stats->max_dup_opno = -1;
3108 stats->min_scratch_opno = -1;
3109 stats->max_scratch_opno = -1;
3110 stats->num_dups = 0;
3112 len = GET_NUM_ELEM (pattern);
3113 for (i = 0; i < len; i++)
3114 get_pattern_stats_1 (stats, RTVEC_ELT (pattern, i));
3116 stats->num_generator_args = stats->max_opno + 1;
3117 stats->num_insn_operands = MAX (stats->max_opno,
3118 stats->max_scratch_opno) + 1;
3119 stats->num_operand_vars = MAX (stats->max_opno,
3120 MAX (stats->max_dup_opno,
3121 stats->max_scratch_opno)) + 1;
3124 /* Return the emit_* function that should be used for pattern X, or NULL
3125 if we can't pick a particular type at compile time and should instead
3126 fall back to "emit". */
3128 const char *
3129 get_emit_function (rtx x)
3131 switch (classify_insn (x))
3133 case INSN:
3134 return "emit_insn";
3136 case CALL_INSN:
3137 return "emit_call_insn";
3139 case JUMP_INSN:
3140 return "emit_jump_insn";
3142 case UNKNOWN:
3143 return NULL;
3145 default:
3146 gcc_unreachable ();
3150 /* Return true if we must emit a barrier after pattern X. */
3152 bool
3153 needs_barrier_p (rtx x)
3155 return (GET_CODE (x) == SET
3156 && GET_CODE (SET_DEST (x)) == PC
3157 && GET_CODE (SET_SRC (x)) == LABEL_REF);
3160 #define NS "NULL"
3161 #define ZS "'\\0'"
3162 #define OPTAB_CL(o, p, c, b, l) { #o, p, #b, ZS, #l, o, c, UNKNOWN, 1 },
3163 #define OPTAB_CX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 1 },
3164 #define OPTAB_CD(o, p) { #o, p, NS, ZS, NS, o, UNKNOWN, UNKNOWN, 2 },
3165 #define OPTAB_NL(o, p, c, b, s, l) { #o, p, #b, #s, #l, o, c, c, 3 },
3166 #define OPTAB_NC(o, p, c) { #o, p, NS, ZS, NS, o, c, c, 3 },
3167 #define OPTAB_NX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 3 },
3168 #define OPTAB_VL(o, p, c, b, s, l) { #o, p, #b, #s, #l, o, c, UNKNOWN, 3 },
3169 #define OPTAB_VC(o, p, c) { #o, p, NS, ZS, NS, o, c, UNKNOWN, 3 },
3170 #define OPTAB_VX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 3 },
3171 #define OPTAB_DC(o, p, c) { #o, p, NS, ZS, NS, o, c, c, 4 },
3172 #define OPTAB_D(o, p) { #o, p, NS, ZS, NS, o, UNKNOWN, UNKNOWN, 4 },
3174 /* An array of all optabs. Note that the same optab can appear more
3175 than once, with a different pattern. */
3176 optab_def optabs[] = {
3177 { "unknown_optab", NULL, NS, ZS, NS, unknown_optab, UNKNOWN, UNKNOWN, 0 },
3178 #include "optabs.def"
3181 /* The number of entries in optabs[]. */
3182 unsigned int num_optabs = ARRAY_SIZE (optabs);
3184 #undef OPTAB_CL
3185 #undef OPTAB_CX
3186 #undef OPTAB_CD
3187 #undef OPTAB_NL
3188 #undef OPTAB_NC
3189 #undef OPTAB_NX
3190 #undef OPTAB_VL
3191 #undef OPTAB_VC
3192 #undef OPTAB_VX
3193 #undef OPTAB_DC
3194 #undef OPTAB_D
3196 /* Return true if instruction NAME matches pattern PAT, storing information
3197 about the match in P if so. */
3199 static bool
3200 match_pattern (optab_pattern *p, const char *name, const char *pat)
3202 bool force_float = false;
3203 bool force_int = false;
3204 bool force_partial_int = false;
3205 bool force_fixed = false;
3207 if (pat == NULL)
3208 return false;
3209 for (; ; ++pat)
3211 if (*pat != '$')
3213 if (*pat != *name++)
3214 return false;
3215 if (*pat == '\0')
3216 return true;
3217 continue;
3219 switch (*++pat)
3221 case 'I':
3222 force_int = 1;
3223 break;
3224 case 'P':
3225 force_partial_int = 1;
3226 break;
3227 case 'F':
3228 force_float = 1;
3229 break;
3230 case 'Q':
3231 force_fixed = 1;
3232 break;
3234 case 'a':
3235 case 'b':
3237 int i;
3239 /* This loop will stop at the first prefix match, so
3240 look through the modes in reverse order, in case
3241 there are extra CC modes and CC is a prefix of the
3242 CC modes (as it should be). */
3243 for (i = (MAX_MACHINE_MODE) - 1; i >= 0; i--)
3245 const char *p, *q;
3246 for (p = GET_MODE_NAME (i), q = name; *p; p++, q++)
3247 if (TOLOWER (*p) != *q)
3248 break;
3249 if (*p == 0
3250 && (! force_int || mode_class[i] == MODE_INT
3251 || mode_class[i] == MODE_VECTOR_INT)
3252 && (! force_partial_int
3253 || mode_class[i] == MODE_INT
3254 || mode_class[i] == MODE_PARTIAL_INT
3255 || mode_class[i] == MODE_VECTOR_INT)
3256 && (! force_float
3257 || mode_class[i] == MODE_FLOAT
3258 || mode_class[i] == MODE_DECIMAL_FLOAT
3259 || mode_class[i] == MODE_COMPLEX_FLOAT
3260 || mode_class[i] == MODE_VECTOR_FLOAT)
3261 && (! force_fixed
3262 || mode_class[i] == MODE_FRACT
3263 || mode_class[i] == MODE_UFRACT
3264 || mode_class[i] == MODE_ACCUM
3265 || mode_class[i] == MODE_UACCUM
3266 || mode_class[i] == MODE_VECTOR_FRACT
3267 || mode_class[i] == MODE_VECTOR_UFRACT
3268 || mode_class[i] == MODE_VECTOR_ACCUM
3269 || mode_class[i] == MODE_VECTOR_UACCUM))
3270 break;
3273 if (i < 0)
3274 return false;
3275 name += strlen (GET_MODE_NAME (i));
3276 if (*pat == 'a')
3277 p->m1 = i;
3278 else
3279 p->m2 = i;
3281 force_int = false;
3282 force_partial_int = false;
3283 force_float = false;
3284 force_fixed = false;
3286 break;
3288 default:
3289 gcc_unreachable ();
3294 /* Return true if NAME is the name of an optab, describing it in P if so. */
3296 bool
3297 find_optab (optab_pattern *p, const char *name)
3299 if (*name == 0 || *name == '*')
3300 return false;
3302 /* See if NAME matches one of the patterns we have for the optabs
3303 we know about. */
3304 for (unsigned int pindex = 0; pindex < ARRAY_SIZE (optabs); pindex++)
3306 p->m1 = p->m2 = 0;
3307 if (match_pattern (p, name, optabs[pindex].pattern))
3309 p->name = name;
3310 p->op = optabs[pindex].op;
3311 p->sort_num = (p->op << 16) | (p->m2 << 8) | p->m1;
3312 return true;
3315 return false;