[Ada] Add special bypass for obsolete code pattern
[official-gcc.git] / gcc / gensupport.c
blob1aab711990184346eda51391c01b37aeb35b7d73
1 /* Support routines for the various generation passes.
2 Copyright (C) 2000-2019 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_ADDRESS_CONSTRAINT:
586 queue_pattern (desc, &define_pred_tail, loc);
587 break;
589 case DEFINE_INSN_AND_SPLIT:
590 case DEFINE_INSN_AND_REWRITE:
592 const char *split_cond;
593 rtx split;
594 rtvec attr;
595 int i;
596 class queue_elem *insn_elem;
597 class queue_elem *split_elem;
598 int split_code = (GET_CODE (desc) == DEFINE_INSN_AND_REWRITE ? 5 : 6);
600 /* Create a split with values from the insn_and_split. */
601 split = rtx_alloc (DEFINE_SPLIT);
603 i = XVECLEN (desc, 1);
604 XVEC (split, 0) = rtvec_alloc (i);
605 while (--i >= 0)
607 XVECEXP (split, 0, i) = copy_rtx (XVECEXP (desc, 1, i));
608 remove_constraints (XVECEXP (split, 0, i));
611 /* If the split condition starts with "&&", append it to the
612 insn condition to create the new split condition. */
613 split_cond = XSTR (desc, 4);
614 if (split_cond[0] == '&' && split_cond[1] == '&')
616 rtx_reader_ptr->copy_md_ptr_loc (split_cond + 2, split_cond);
617 split_cond = rtx_reader_ptr->join_c_conditions (XSTR (desc, 2),
618 split_cond + 2);
620 else if (GET_CODE (desc) == DEFINE_INSN_AND_REWRITE)
621 error_at (loc, "the rewrite condition must start with `&&'");
622 XSTR (split, 1) = split_cond;
623 if (GET_CODE (desc) == DEFINE_INSN_AND_REWRITE)
624 XVEC (split, 2) = gen_rewrite_sequence (XVEC (desc, 1));
625 else
626 XVEC (split, 2) = XVEC (desc, 5);
627 XSTR (split, 3) = XSTR (desc, split_code);
629 /* Fix up the DEFINE_INSN. */
630 attr = XVEC (desc, split_code + 1);
631 PUT_CODE (desc, DEFINE_INSN);
632 XVEC (desc, 4) = attr;
634 /* Queue them. */
635 insn_elem = queue_pattern (desc, &define_insn_tail, loc);
636 split_elem = queue_pattern (split, &other_tail, loc);
637 insn_elem->split = split_elem;
638 break;
641 default:
642 queue_pattern (desc, &other_tail, loc);
643 break;
647 /* Return true if attribute PREDICABLE is true for ELEM, which holds
648 a DEFINE_INSN. */
650 static int
651 is_predicable (class queue_elem *elem)
653 rtvec vec = XVEC (elem->data, 4);
654 const char *value;
655 int i;
657 if (! vec)
658 return predicable_default;
660 for (i = GET_NUM_ELEM (vec) - 1; i >= 0; --i)
662 rtx sub = RTVEC_ELT (vec, i);
663 switch (GET_CODE (sub))
665 case SET_ATTR:
666 if (strcmp (XSTR (sub, 0), "predicable") == 0)
668 value = XSTR (sub, 1);
669 goto found;
671 break;
673 case SET_ATTR_ALTERNATIVE:
674 if (strcmp (XSTR (sub, 0), "predicable") == 0)
676 error_at (elem->loc, "multiple alternatives for `predicable'");
677 return 0;
679 break;
681 case SET:
682 if (GET_CODE (SET_DEST (sub)) != ATTR
683 || strcmp (XSTR (SET_DEST (sub), 0), "predicable") != 0)
684 break;
685 sub = SET_SRC (sub);
686 if (GET_CODE (sub) == CONST_STRING)
688 value = XSTR (sub, 0);
689 goto found;
692 /* ??? It would be possible to handle this if we really tried.
693 It's not easy though, and I'm not going to bother until it
694 really proves necessary. */
695 error_at (elem->loc, "non-constant value for `predicable'");
696 return 0;
698 default:
699 gcc_unreachable ();
703 return predicable_default;
705 found:
706 /* Find out which value we're looking at. Multiple alternatives means at
707 least one is predicable. */
708 if (strchr (value, ',') != NULL)
709 return 1;
710 if (strcmp (value, predicable_true) == 0)
711 return 1;
712 if (strcmp (value, predicable_false) == 0)
713 return 0;
715 error_at (elem->loc, "unknown value `%s' for `predicable' attribute", value);
716 return 0;
719 /* Find attribute SUBST in ELEM and assign NEW_VALUE to it. */
720 static void
721 change_subst_attribute (class queue_elem *elem,
722 class queue_elem *subst_elem,
723 const char *new_value)
725 rtvec attrs_vec = XVEC (elem->data, 4);
726 const char *subst_name = XSTR (subst_elem->data, 0);
727 int i;
729 if (! attrs_vec)
730 return;
732 for (i = GET_NUM_ELEM (attrs_vec) - 1; i >= 0; --i)
734 rtx cur_attr = RTVEC_ELT (attrs_vec, i);
735 if (GET_CODE (cur_attr) != SET_ATTR)
736 continue;
737 if (strcmp (XSTR (cur_attr, 0), subst_name) == 0)
739 XSTR (cur_attr, 1) = new_value;
740 return;
745 /* Return true if ELEM has the attribute with the name of DEFINE_SUBST
746 represented by SUBST_ELEM and this attribute has value SUBST_TRUE.
747 DEFINE_SUBST isn't applied to patterns without such attribute. In other
748 words, we suppose the default value of the attribute to be 'no' since it is
749 always generated automatically in read-rtl.c. */
750 static bool
751 has_subst_attribute (class queue_elem *elem, class queue_elem *subst_elem)
753 rtvec attrs_vec = XVEC (elem->data, 4);
754 const char *value, *subst_name = XSTR (subst_elem->data, 0);
755 int i;
757 if (! attrs_vec)
758 return false;
760 for (i = GET_NUM_ELEM (attrs_vec) - 1; i >= 0; --i)
762 rtx cur_attr = RTVEC_ELT (attrs_vec, i);
763 switch (GET_CODE (cur_attr))
765 case SET_ATTR:
766 if (strcmp (XSTR (cur_attr, 0), subst_name) == 0)
768 value = XSTR (cur_attr, 1);
769 goto found;
771 break;
773 case SET:
774 if (GET_CODE (SET_DEST (cur_attr)) != ATTR
775 || strcmp (XSTR (SET_DEST (cur_attr), 0), subst_name) != 0)
776 break;
777 cur_attr = SET_SRC (cur_attr);
778 if (GET_CODE (cur_attr) == CONST_STRING)
780 value = XSTR (cur_attr, 0);
781 goto found;
784 /* Only (set_attr "subst" "yes/no") and
785 (set (attr "subst" (const_string "yes/no")))
786 are currently allowed. */
787 error_at (elem->loc, "unsupported value for `%s'", subst_name);
788 return false;
790 case SET_ATTR_ALTERNATIVE:
791 error_at (elem->loc,
792 "%s: `set_attr_alternative' is unsupported by "
793 "`define_subst'", XSTR (elem->data, 0));
794 return false;
797 default:
798 gcc_unreachable ();
802 return false;
804 found:
805 if (strcmp (value, subst_true) == 0)
806 return true;
807 if (strcmp (value, subst_false) == 0)
808 return false;
810 error_at (elem->loc, "unknown value `%s' for `%s' attribute",
811 value, subst_name);
812 return false;
815 /* Compare RTL-template of original define_insn X to input RTL-template of
816 define_subst PT. Return 1 if the templates match, 0 otherwise.
817 During the comparison, the routine also fills global_array OPERAND_DATA. */
818 static bool
819 subst_pattern_match (rtx x, rtx pt, file_location loc)
821 RTX_CODE code, code_pt;
822 int i, j, len;
823 const char *fmt, *pred_name;
825 code = GET_CODE (x);
826 code_pt = GET_CODE (pt);
828 if (code_pt == MATCH_OPERAND)
830 /* MATCH_DUP, and MATCH_OP_DUP don't have a specified mode, so we
831 always accept them. */
832 if (GET_MODE (pt) != VOIDmode && GET_MODE (x) != GET_MODE (pt)
833 && (code != MATCH_DUP && code != MATCH_OP_DUP))
834 return false; /* Modes don't match. */
836 if (code == MATCH_OPERAND)
838 pred_name = XSTR (pt, 1);
839 if (pred_name[0] != 0)
841 const struct pred_data *pred_pt = lookup_predicate (pred_name);
842 if (!pred_pt || pred_pt != lookup_predicate (XSTR (x, 1)))
843 return false; /* Predicates don't match. */
847 gcc_assert (XINT (pt, 0) >= 0 && XINT (pt, 0) < MAX_OPERANDS);
848 operand_data[XINT (pt, 0)] = x;
849 return true;
852 if (code_pt == MATCH_OPERATOR)
854 int x_vecexp_pos = -1;
856 /* Compare modes. */
857 if (GET_MODE (pt) != VOIDmode && GET_MODE (x) != GET_MODE (pt))
858 return false;
860 /* In case X is also match_operator, compare predicates. */
861 if (code == MATCH_OPERATOR)
863 pred_name = XSTR (pt, 1);
864 if (pred_name[0] != 0)
866 const struct pred_data *pred_pt = lookup_predicate (pred_name);
867 if (!pred_pt || pred_pt != lookup_predicate (XSTR (x, 1)))
868 return false;
872 /* Compare operands.
873 MATCH_OPERATOR in input template could match in original template
874 either 1) MATCH_OPERAND, 2) UNSPEC, 3) ordinary operation (like PLUS).
875 In the first case operands are at (XVECEXP (x, 2, j)), in the second
876 - at (XVECEXP (x, 0, j)), in the last one - (XEXP (x, j)).
877 X_VECEXP_POS variable shows, where to look for these operands. */
878 if (code == UNSPEC
879 || code == UNSPEC_VOLATILE)
880 x_vecexp_pos = 0;
881 else if (code == MATCH_OPERATOR)
882 x_vecexp_pos = 2;
883 else
884 x_vecexp_pos = -1;
886 /* MATCH_OPERATOR or UNSPEC case. */
887 if (x_vecexp_pos >= 0)
889 /* Compare operands number in X and PT. */
890 if (XVECLEN (x, x_vecexp_pos) != XVECLEN (pt, 2))
891 return false;
892 for (j = 0; j < XVECLEN (pt, 2); j++)
893 if (!subst_pattern_match (XVECEXP (x, x_vecexp_pos, j),
894 XVECEXP (pt, 2, j), loc))
895 return false;
898 /* Ordinary operator. */
899 else
901 /* Compare operands number in X and PT.
902 We count operands differently for X and PT since we compare
903 an operator (with operands directly in RTX) and MATCH_OPERATOR
904 (that has a vector with operands). */
905 if (GET_RTX_LENGTH (code) != XVECLEN (pt, 2))
906 return false;
907 for (j = 0; j < XVECLEN (pt, 2); j++)
908 if (!subst_pattern_match (XEXP (x, j), XVECEXP (pt, 2, j), loc))
909 return false;
912 /* Store the operand to OPERAND_DATA array. */
913 gcc_assert (XINT (pt, 0) >= 0 && XINT (pt, 0) < MAX_OPERANDS);
914 operand_data[XINT (pt, 0)] = x;
915 return true;
918 if (code_pt == MATCH_PAR_DUP
919 || code_pt == MATCH_DUP
920 || code_pt == MATCH_OP_DUP
921 || code_pt == MATCH_SCRATCH
922 || code_pt == MATCH_PARALLEL)
924 /* Currently interface for these constructions isn't defined -
925 probably they aren't needed in input template of define_subst at all.
926 So, for now their usage in define_subst is forbidden. */
927 error_at (loc, "%s cannot be used in define_subst",
928 GET_RTX_NAME (code_pt));
931 gcc_assert (code != MATCH_PAR_DUP
932 && code_pt != MATCH_DUP
933 && code_pt != MATCH_OP_DUP
934 && code_pt != MATCH_SCRATCH
935 && code_pt != MATCH_PARALLEL
936 && code_pt != MATCH_OPERAND
937 && code_pt != MATCH_OPERATOR);
938 /* If PT is none of the handled above, then we match only expressions with
939 the same code in X. */
940 if (code != code_pt)
941 return false;
943 fmt = GET_RTX_FORMAT (code_pt);
944 len = GET_RTX_LENGTH (code_pt);
946 for (i = 0; i < len; i++)
948 if (fmt[i] == '0')
949 break;
951 switch (fmt[i])
953 case 'r': case 'p': case 'i': case 'w': case 's':
954 continue;
956 case 'e': case 'u':
957 if (!subst_pattern_match (XEXP (x, i), XEXP (pt, i), loc))
958 return false;
959 break;
960 case 'E':
962 if (XVECLEN (x, i) != XVECLEN (pt, i))
963 return false;
964 for (j = 0; j < XVECLEN (pt, i); j++)
965 if (!subst_pattern_match (XVECEXP (x, i, j),
966 XVECEXP (pt, i, j), loc))
967 return false;
968 break;
970 default:
971 gcc_unreachable ();
975 return true;
978 /* Examine the attribute "predicable"; discover its boolean values
979 and its default. */
981 static void
982 identify_predicable_attribute (void)
984 class queue_elem *elem;
985 char *p_true, *p_false;
986 const char *value;
988 /* Look for the DEFINE_ATTR for `predicable', which must exist. */
989 for (elem = define_attr_queue; elem ; elem = elem->next)
990 if (strcmp (XSTR (elem->data, 0), "predicable") == 0)
991 goto found;
993 error_at (define_cond_exec_queue->loc,
994 "attribute `predicable' not defined");
995 return;
997 found:
998 value = XSTR (elem->data, 1);
999 p_false = xstrdup (value);
1000 p_true = strchr (p_false, ',');
1001 if (p_true == NULL || strchr (++p_true, ',') != NULL)
1003 error_at (elem->loc, "attribute `predicable' is not a boolean");
1004 free (p_false);
1005 return;
1007 p_true[-1] = '\0';
1009 predicable_true = p_true;
1010 predicable_false = p_false;
1012 switch (GET_CODE (XEXP (elem->data, 2)))
1014 case CONST_STRING:
1015 value = XSTR (XEXP (elem->data, 2), 0);
1016 break;
1018 case CONST:
1019 error_at (elem->loc, "attribute `predicable' cannot be const");
1020 free (p_false);
1021 return;
1023 default:
1024 error_at (elem->loc,
1025 "attribute `predicable' must have a constant default");
1026 free (p_false);
1027 return;
1030 if (strcmp (value, p_true) == 0)
1031 predicable_default = 1;
1032 else if (strcmp (value, p_false) == 0)
1033 predicable_default = 0;
1034 else
1036 error_at (elem->loc, "unknown value `%s' for `predicable' attribute",
1037 value);
1038 free (p_false);
1042 /* Return the number of alternatives in constraint S. */
1044 static int
1045 n_alternatives (const char *s)
1047 int n = 1;
1049 if (s)
1050 while (*s)
1051 n += (*s++ == ',');
1053 return n;
1056 /* The routine scans rtl PATTERN, find match_operand in it and counts
1057 number of alternatives. If PATTERN contains several match_operands
1058 with different number of alternatives, error is emitted, and the
1059 routine returns 0. If all match_operands in PATTERN have the same
1060 number of alternatives, it's stored in N_ALT, and the routine returns 1.
1061 LOC is the location of PATTERN, for error reporting. */
1062 static int
1063 get_alternatives_number (rtx pattern, int *n_alt, file_location loc)
1065 const char *fmt;
1066 enum rtx_code code;
1067 int i, j, len;
1069 if (!n_alt)
1070 return 0;
1072 code = GET_CODE (pattern);
1073 switch (code)
1075 case MATCH_OPERAND:
1076 i = n_alternatives (XSTR (pattern, 2));
1077 /* n_alternatives returns 1 if constraint string is empty -
1078 here we fix it up. */
1079 if (!*(XSTR (pattern, 2)))
1080 i = 0;
1081 if (*n_alt <= 0)
1082 *n_alt = i;
1084 else if (i && i != *n_alt)
1086 error_at (loc, "wrong number of alternatives in operand %d",
1087 XINT (pattern, 0));
1088 return 0;
1091 default:
1092 break;
1095 fmt = GET_RTX_FORMAT (code);
1096 len = GET_RTX_LENGTH (code);
1097 for (i = 0; i < len; i++)
1099 switch (fmt[i])
1101 case 'e': case 'u':
1102 if (!get_alternatives_number (XEXP (pattern, i), n_alt, loc))
1103 return 0;
1104 break;
1106 case 'V':
1107 if (XVEC (pattern, i) == NULL)
1108 break;
1109 /* FALLTHRU */
1111 case 'E':
1112 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
1113 if (!get_alternatives_number (XVECEXP (pattern, i, j), n_alt, loc))
1114 return 0;
1115 break;
1117 case 'r': case 'p': case 'i': case 'w':
1118 case '0': case 's': case 'S': case 'T':
1119 break;
1121 default:
1122 gcc_unreachable ();
1125 return 1;
1128 /* Determine how many alternatives there are in INSN, and how many
1129 operands. */
1131 static void
1132 collect_insn_data (rtx pattern, int *palt, int *pmax)
1134 const char *fmt;
1135 enum rtx_code code;
1136 int i, j, len;
1138 code = GET_CODE (pattern);
1139 switch (code)
1141 case MATCH_OPERAND:
1142 case MATCH_SCRATCH:
1143 i = n_alternatives (XSTR (pattern, code == MATCH_SCRATCH ? 1 : 2));
1144 *palt = (i > *palt ? i : *palt);
1145 /* Fall through. */
1147 case MATCH_OPERATOR:
1148 case MATCH_PARALLEL:
1149 i = XINT (pattern, 0);
1150 if (i > *pmax)
1151 *pmax = i;
1152 break;
1154 default:
1155 break;
1158 fmt = GET_RTX_FORMAT (code);
1159 len = GET_RTX_LENGTH (code);
1160 for (i = 0; i < len; i++)
1162 switch (fmt[i])
1164 case 'e': case 'u':
1165 collect_insn_data (XEXP (pattern, i), palt, pmax);
1166 break;
1168 case 'V':
1169 if (XVEC (pattern, i) == NULL)
1170 break;
1171 /* Fall through. */
1172 case 'E':
1173 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
1174 collect_insn_data (XVECEXP (pattern, i, j), palt, pmax);
1175 break;
1177 case 'r': case 'p': case 'i': case 'w':
1178 case '0': case 's': case 'S': case 'T':
1179 break;
1181 default:
1182 gcc_unreachable ();
1187 static rtx
1188 alter_predicate_for_insn (rtx pattern, int alt, int max_op,
1189 file_location loc)
1191 const char *fmt;
1192 enum rtx_code code;
1193 int i, j, len;
1195 code = GET_CODE (pattern);
1196 switch (code)
1198 case MATCH_OPERAND:
1200 const char *c = XSTR (pattern, 2);
1202 if (n_alternatives (c) != 1)
1204 error_at (loc, "too many alternatives for operand %d",
1205 XINT (pattern, 0));
1206 return NULL;
1209 /* Replicate C as needed to fill out ALT alternatives. */
1210 if (c && *c && alt > 1)
1212 size_t c_len = strlen (c);
1213 size_t len = alt * (c_len + 1);
1214 char *new_c = XNEWVEC (char, len);
1216 memcpy (new_c, c, c_len);
1217 for (i = 1; i < alt; ++i)
1219 new_c[i * (c_len + 1) - 1] = ',';
1220 memcpy (&new_c[i * (c_len + 1)], c, c_len);
1222 new_c[len - 1] = '\0';
1223 XSTR (pattern, 2) = new_c;
1226 /* Fall through. */
1228 case MATCH_OPERATOR:
1229 case MATCH_SCRATCH:
1230 case MATCH_PARALLEL:
1231 XINT (pattern, 0) += max_op;
1232 break;
1234 default:
1235 break;
1238 fmt = GET_RTX_FORMAT (code);
1239 len = GET_RTX_LENGTH (code);
1240 for (i = 0; i < len; i++)
1242 rtx r;
1244 switch (fmt[i])
1246 case 'e': case 'u':
1247 r = alter_predicate_for_insn (XEXP (pattern, i), alt, max_op, loc);
1248 if (r == NULL)
1249 return r;
1250 break;
1252 case 'E':
1253 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
1255 r = alter_predicate_for_insn (XVECEXP (pattern, i, j),
1256 alt, max_op, loc);
1257 if (r == NULL)
1258 return r;
1260 break;
1262 case 'r': case 'p': case 'i': case 'w': case '0': case 's':
1263 break;
1265 default:
1266 gcc_unreachable ();
1270 return pattern;
1273 /* Duplicate constraints in PATTERN. If pattern is from original
1274 rtl-template, we need to duplicate each alternative - for that we
1275 need to use duplicate_each_alternative () as a functor ALTER.
1276 If pattern is from output-pattern of define_subst, we need to
1277 duplicate constraints in another way - with duplicate_alternatives ().
1278 N_DUP is multiplication factor. */
1279 static rtx
1280 alter_constraints (rtx pattern, int n_dup, constraints_handler_t alter)
1282 const char *fmt;
1283 enum rtx_code code;
1284 int i, j, len;
1286 code = GET_CODE (pattern);
1287 switch (code)
1289 case MATCH_OPERAND:
1290 XSTR (pattern, 2) = alter (XSTR (pattern, 2), n_dup);
1291 break;
1293 default:
1294 break;
1297 fmt = GET_RTX_FORMAT (code);
1298 len = GET_RTX_LENGTH (code);
1299 for (i = 0; i < len; i++)
1301 rtx r;
1303 switch (fmt[i])
1305 case 'e': case 'u':
1306 r = alter_constraints (XEXP (pattern, i), n_dup, alter);
1307 if (r == NULL)
1308 return r;
1309 break;
1311 case 'E':
1312 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
1314 r = alter_constraints (XVECEXP (pattern, i, j), n_dup, alter);
1315 if (r == NULL)
1316 return r;
1318 break;
1320 case 'r': case 'p': case 'i': case 'w': case '0': case 's':
1321 break;
1323 default:
1324 break;
1328 return pattern;
1331 static const char *
1332 alter_test_for_insn (class queue_elem *ce_elem,
1333 class queue_elem *insn_elem)
1335 return rtx_reader_ptr->join_c_conditions (XSTR (ce_elem->data, 1),
1336 XSTR (insn_elem->data, 2));
1339 /* Modify VAL, which is an attribute expression for the "enabled" attribute,
1340 to take "ce_enabled" into account. Return the new expression. */
1341 static rtx
1342 modify_attr_enabled_ce (rtx val)
1344 rtx eq_attr, str;
1345 rtx ite;
1346 eq_attr = rtx_alloc (EQ_ATTR);
1347 ite = rtx_alloc (IF_THEN_ELSE);
1348 str = rtx_alloc (CONST_STRING);
1350 XSTR (eq_attr, 0) = "ce_enabled";
1351 XSTR (eq_attr, 1) = "yes";
1352 XSTR (str, 0) = "no";
1353 XEXP (ite, 0) = eq_attr;
1354 XEXP (ite, 1) = val;
1355 XEXP (ite, 2) = str;
1357 return ite;
1360 /* Alter the attribute vector of INSN, which is a COND_EXEC variant created
1361 from a define_insn pattern. We must modify the "predicable" attribute
1362 to be named "ce_enabled", and also change any "enabled" attribute that's
1363 present so that it takes ce_enabled into account.
1364 We rely on the fact that INSN was created with copy_rtx, and modify data
1365 in-place. */
1367 static void
1368 alter_attrs_for_insn (rtx insn)
1370 static bool global_changes_made = false;
1371 rtvec vec = XVEC (insn, 4);
1372 rtvec new_vec;
1373 rtx val, set;
1374 int num_elem;
1375 int predicable_idx = -1;
1376 int enabled_idx = -1;
1377 int i;
1379 if (! vec)
1380 return;
1382 num_elem = GET_NUM_ELEM (vec);
1383 for (i = num_elem - 1; i >= 0; --i)
1385 rtx sub = RTVEC_ELT (vec, i);
1386 switch (GET_CODE (sub))
1388 case SET_ATTR:
1389 if (strcmp (XSTR (sub, 0), "predicable") == 0)
1391 predicable_idx = i;
1392 XSTR (sub, 0) = "ce_enabled";
1394 else if (strcmp (XSTR (sub, 0), "enabled") == 0)
1396 enabled_idx = i;
1397 XSTR (sub, 0) = "nonce_enabled";
1399 break;
1401 case SET_ATTR_ALTERNATIVE:
1402 if (strcmp (XSTR (sub, 0), "predicable") == 0)
1403 /* We already give an error elsewhere. */
1404 return;
1405 else if (strcmp (XSTR (sub, 0), "enabled") == 0)
1407 enabled_idx = i;
1408 XSTR (sub, 0) = "nonce_enabled";
1410 break;
1412 case SET:
1413 if (GET_CODE (SET_DEST (sub)) != ATTR)
1414 break;
1415 if (strcmp (XSTR (SET_DEST (sub), 0), "predicable") == 0)
1417 sub = SET_SRC (sub);
1418 if (GET_CODE (sub) == CONST_STRING)
1420 predicable_idx = i;
1421 XSTR (sub, 0) = "ce_enabled";
1423 else
1424 /* We already give an error elsewhere. */
1425 return;
1426 break;
1428 if (strcmp (XSTR (SET_DEST (sub), 0), "enabled") == 0)
1430 enabled_idx = i;
1431 XSTR (SET_DEST (sub), 0) = "nonce_enabled";
1433 break;
1435 default:
1436 gcc_unreachable ();
1439 if (predicable_idx == -1)
1440 return;
1442 if (!global_changes_made)
1444 class queue_elem *elem;
1446 global_changes_made = true;
1447 add_define_attr ("ce_enabled");
1448 add_define_attr ("nonce_enabled");
1450 for (elem = define_attr_queue; elem ; elem = elem->next)
1451 if (strcmp (XSTR (elem->data, 0), "enabled") == 0)
1453 XEXP (elem->data, 2)
1454 = modify_attr_enabled_ce (XEXP (elem->data, 2));
1457 if (enabled_idx == -1)
1458 return;
1460 new_vec = rtvec_alloc (num_elem + 1);
1461 for (i = 0; i < num_elem; i++)
1462 RTVEC_ELT (new_vec, i) = RTVEC_ELT (vec, i);
1463 val = rtx_alloc (IF_THEN_ELSE);
1464 XEXP (val, 0) = rtx_alloc (EQ_ATTR);
1465 XEXP (val, 1) = rtx_alloc (CONST_STRING);
1466 XEXP (val, 2) = rtx_alloc (CONST_STRING);
1467 XSTR (XEXP (val, 0), 0) = "nonce_enabled";
1468 XSTR (XEXP (val, 0), 1) = "yes";
1469 XSTR (XEXP (val, 1), 0) = "yes";
1470 XSTR (XEXP (val, 2), 0) = "no";
1471 set = rtx_alloc (SET);
1472 SET_DEST (set) = rtx_alloc (ATTR);
1473 XSTR (SET_DEST (set), 0) = "enabled";
1474 SET_SRC (set) = modify_attr_enabled_ce (val);
1475 RTVEC_ELT (new_vec, i) = set;
1476 XVEC (insn, 4) = new_vec;
1479 /* As number of constraints is changed after define_subst, we need to
1480 process attributes as well - we need to duplicate them the same way
1481 that we duplicated constraints in original pattern
1482 ELEM is a queue element, containing our rtl-template,
1483 N_DUP - multiplication factor. */
1484 static void
1485 alter_attrs_for_subst_insn (class queue_elem * elem, int n_dup)
1487 rtvec vec = XVEC (elem->data, 4);
1488 int num_elem;
1489 int i;
1491 if (n_dup < 2 || ! vec)
1492 return;
1494 num_elem = GET_NUM_ELEM (vec);
1495 for (i = num_elem - 1; i >= 0; --i)
1497 rtx sub = RTVEC_ELT (vec, i);
1498 switch (GET_CODE (sub))
1500 case SET_ATTR:
1501 if (strchr (XSTR (sub, 1), ',') != NULL)
1502 XSTR (sub, 1) = duplicate_alternatives (XSTR (sub, 1), n_dup);
1503 break;
1505 case SET_ATTR_ALTERNATIVE:
1506 case SET:
1507 error_at (elem->loc,
1508 "%s: `define_subst' does not support attributes "
1509 "assigned by `set' and `set_attr_alternative'",
1510 XSTR (elem->data, 0));
1511 return;
1513 default:
1514 gcc_unreachable ();
1519 /* Adjust all of the operand numbers in SRC to match the shift they'll
1520 get from an operand displacement of DISP. Return a pointer after the
1521 adjusted string. */
1523 static char *
1524 shift_output_template (char *dest, const char *src, int disp)
1526 while (*src)
1528 char c = *src++;
1529 *dest++ = c;
1530 if (c == '%')
1532 c = *src++;
1533 if (ISDIGIT ((unsigned char) c))
1534 c += disp;
1535 else if (ISALPHA (c))
1537 *dest++ = c;
1538 c = *src++ + disp;
1540 *dest++ = c;
1544 return dest;
1547 static const char *
1548 alter_output_for_insn (class queue_elem *ce_elem,
1549 class queue_elem *insn_elem,
1550 int alt, int max_op)
1552 const char *ce_out, *insn_out;
1553 char *result, *p;
1554 size_t len, ce_len, insn_len;
1556 /* ??? Could coordinate with genoutput to not duplicate code here. */
1558 ce_out = XSTR (ce_elem->data, 2);
1559 insn_out = XTMPL (insn_elem->data, 3);
1560 if (!ce_out || *ce_out == '\0')
1561 return insn_out;
1563 ce_len = strlen (ce_out);
1564 insn_len = strlen (insn_out);
1566 if (*insn_out == '*')
1567 /* You must take care of the predicate yourself. */
1568 return insn_out;
1570 if (*insn_out == '@')
1572 len = (ce_len + 1) * alt + insn_len + 1;
1573 p = result = XNEWVEC (char, len);
1578 *p++ = *insn_out++;
1579 while (ISSPACE ((unsigned char) *insn_out));
1581 if (*insn_out != '#')
1583 p = shift_output_template (p, ce_out, max_op);
1584 *p++ = ' ';
1588 *p++ = *insn_out++;
1589 while (*insn_out && *insn_out != '\n');
1591 while (*insn_out);
1592 *p = '\0';
1594 else
1596 len = ce_len + 1 + insn_len + 1;
1597 result = XNEWVEC (char, len);
1599 p = shift_output_template (result, ce_out, max_op);
1600 *p++ = ' ';
1601 memcpy (p, insn_out, insn_len + 1);
1604 return result;
1607 /* From string STR "a,b,c" produce "a,b,c,a,b,c,a,b,c", i.e. original
1608 string, duplicated N_DUP times. */
1610 static const char *
1611 duplicate_alternatives (const char * str, int n_dup)
1613 int i, len, new_len;
1614 char *result, *sp;
1615 const char *cp;
1617 if (n_dup < 2)
1618 return str;
1620 while (ISSPACE (*str))
1621 str++;
1623 if (*str == '\0')
1624 return str;
1626 cp = str;
1627 len = strlen (str);
1628 new_len = (len + 1) * n_dup;
1630 sp = result = XNEWVEC (char, new_len);
1632 /* Global modifier characters mustn't be duplicated: skip if found. */
1633 if (*cp == '=' || *cp == '+' || *cp == '%')
1635 *sp++ = *cp++;
1636 len--;
1639 /* Copy original constraints N_DUP times. */
1640 for (i = 0; i < n_dup; i++, sp += len+1)
1642 memcpy (sp, cp, len);
1643 *(sp+len) = (i == n_dup - 1) ? '\0' : ',';
1646 return result;
1649 /* From string STR "a,b,c" produce "a,a,a,b,b,b,c,c,c", i.e. string where
1650 each alternative from the original string is duplicated N_DUP times. */
1651 static const char *
1652 duplicate_each_alternative (const char * str, int n_dup)
1654 int i, len, new_len;
1655 char *result, *sp, *ep, *cp;
1657 if (n_dup < 2)
1658 return str;
1660 while (ISSPACE (*str))
1661 str++;
1663 if (*str == '\0')
1664 return str;
1666 cp = xstrdup (str);
1668 new_len = (strlen (cp) + 1) * n_dup;
1670 sp = result = XNEWVEC (char, new_len);
1672 /* Global modifier characters mustn't be duplicated: skip if found. */
1673 if (*cp == '=' || *cp == '+' || *cp == '%')
1674 *sp++ = *cp++;
1678 if ((ep = strchr (cp, ',')) != NULL)
1679 *ep++ = '\0';
1680 len = strlen (cp);
1682 /* Copy a constraint N_DUP times. */
1683 for (i = 0; i < n_dup; i++, sp += len + 1)
1685 memcpy (sp, cp, len);
1686 *(sp+len) = (ep == NULL && i == n_dup - 1) ? '\0' : ',';
1689 cp = ep;
1691 while (cp != NULL);
1693 return result;
1696 /* Alter the output of INSN whose pattern was modified by
1697 DEFINE_SUBST. We must replicate output strings according
1698 to the new number of alternatives ALT in substituted pattern.
1699 If ALT equals 1, output has one alternative or defined by C
1700 code, then output is returned without any changes. */
1702 static const char *
1703 alter_output_for_subst_insn (rtx insn, int alt)
1705 const char *insn_out, *old_out;
1706 char *new_out, *cp;
1707 size_t old_len, new_len;
1708 int j;
1710 insn_out = XTMPL (insn, 3);
1712 if (alt < 2 || *insn_out != '@')
1713 return insn_out;
1715 old_out = insn_out + 1;
1716 while (ISSPACE (*old_out))
1717 old_out++;
1718 old_len = strlen (old_out);
1720 new_len = alt * (old_len + 1) + 1;
1722 new_out = XNEWVEC (char, new_len);
1723 new_out[0] = '@';
1725 for (j = 0, cp = new_out + 1; j < alt; j++, cp += old_len + 1)
1727 memcpy (cp, old_out, old_len);
1728 cp[old_len] = (j == alt - 1) ? '\0' : '\n';
1731 return new_out;
1734 /* Replicate insns as appropriate for the given DEFINE_COND_EXEC. */
1736 static void
1737 process_one_cond_exec (class queue_elem *ce_elem)
1739 class queue_elem *insn_elem;
1740 for (insn_elem = define_insn_queue; insn_elem ; insn_elem = insn_elem->next)
1742 int alternatives, max_operand;
1743 rtx pred, insn, pattern, split;
1744 char *new_name;
1745 int i;
1747 if (! is_predicable (insn_elem))
1748 continue;
1750 alternatives = 1;
1751 max_operand = -1;
1752 collect_insn_data (insn_elem->data, &alternatives, &max_operand);
1753 max_operand += 1;
1755 if (XVECLEN (ce_elem->data, 0) != 1)
1757 error_at (ce_elem->loc, "too many patterns in predicate");
1758 return;
1761 pred = copy_rtx (XVECEXP (ce_elem->data, 0, 0));
1762 pred = alter_predicate_for_insn (pred, alternatives, max_operand,
1763 ce_elem->loc);
1764 if (pred == NULL)
1765 return;
1767 /* Construct a new pattern for the new insn. */
1768 insn = copy_rtx (insn_elem->data);
1769 new_name = XNEWVAR (char, strlen XSTR (insn_elem->data, 0) + 4);
1770 sprintf (new_name, "*p %s", XSTR (insn_elem->data, 0));
1771 XSTR (insn, 0) = new_name;
1772 pattern = rtx_alloc (COND_EXEC);
1773 XEXP (pattern, 0) = pred;
1774 XEXP (pattern, 1) = add_implicit_parallel (XVEC (insn, 1));
1775 XVEC (insn, 1) = rtvec_alloc (1);
1776 XVECEXP (insn, 1, 0) = pattern;
1778 if (XVEC (ce_elem->data, 3) != NULL)
1780 rtvec attributes = rtvec_alloc (XVECLEN (insn, 4)
1781 + XVECLEN (ce_elem->data, 3));
1782 int i = 0;
1783 int j = 0;
1784 for (i = 0; i < XVECLEN (insn, 4); i++)
1785 RTVEC_ELT (attributes, i) = XVECEXP (insn, 4, i);
1787 for (j = 0; j < XVECLEN (ce_elem->data, 3); j++, i++)
1788 RTVEC_ELT (attributes, i) = XVECEXP (ce_elem->data, 3, j);
1790 XVEC (insn, 4) = attributes;
1793 XSTR (insn, 2) = alter_test_for_insn (ce_elem, insn_elem);
1794 XTMPL (insn, 3) = alter_output_for_insn (ce_elem, insn_elem,
1795 alternatives, max_operand);
1796 alter_attrs_for_insn (insn);
1798 /* Put the new pattern on the `other' list so that it
1799 (a) is not reprocessed by other define_cond_exec patterns
1800 (b) appears after all normal define_insn patterns.
1802 ??? B is debatable. If one has normal insns that match
1803 cond_exec patterns, they will be preferred over these
1804 generated patterns. Whether this matters in practice, or if
1805 it's a good thing, or whether we should thread these new
1806 patterns into the define_insn chain just after their generator
1807 is something we'll have to experiment with. */
1809 queue_pattern (insn, &other_tail, insn_elem->loc);
1811 if (!insn_elem->split)
1812 continue;
1814 /* If the original insn came from a define_insn_and_split,
1815 generate a new split to handle the predicated insn. */
1816 split = copy_rtx (insn_elem->split->data);
1817 /* Predicate the pattern matched by the split. */
1818 pattern = rtx_alloc (COND_EXEC);
1819 XEXP (pattern, 0) = pred;
1820 XEXP (pattern, 1) = add_implicit_parallel (XVEC (split, 0));
1821 XVEC (split, 0) = rtvec_alloc (1);
1822 XVECEXP (split, 0, 0) = pattern;
1824 /* Predicate all of the insns generated by the split. */
1825 for (i = 0; i < XVECLEN (split, 2); i++)
1827 pattern = rtx_alloc (COND_EXEC);
1828 XEXP (pattern, 0) = pred;
1829 XEXP (pattern, 1) = XVECEXP (split, 2, i);
1830 XVECEXP (split, 2, i) = pattern;
1832 /* Add the new split to the queue. */
1833 queue_pattern (split, &other_tail, insn_elem->split->loc);
1837 /* Try to apply define_substs to the given ELEM.
1838 Only define_substs, specified via attributes would be applied.
1839 If attribute, requiring define_subst, is set, but no define_subst
1840 was applied, ELEM would be deleted. */
1842 static void
1843 process_substs_on_one_elem (class queue_elem *elem,
1844 class queue_elem *queue)
1846 class queue_elem *subst_elem;
1847 int i, j, patterns_match;
1849 for (subst_elem = define_subst_queue;
1850 subst_elem; subst_elem = subst_elem->next)
1852 int alternatives, alternatives_subst;
1853 rtx subst_pattern;
1854 rtvec subst_pattern_vec;
1856 if (!has_subst_attribute (elem, subst_elem))
1857 continue;
1859 /* Compare original rtl-pattern from define_insn with input
1860 pattern from define_subst.
1861 Also, check if numbers of alternatives are the same in all
1862 match_operands. */
1863 if (XVECLEN (elem->data, 1) != XVECLEN (subst_elem->data, 1))
1864 continue;
1865 patterns_match = 1;
1866 alternatives = -1;
1867 alternatives_subst = -1;
1868 for (j = 0; j < XVECLEN (elem->data, 1); j++)
1870 if (!subst_pattern_match (XVECEXP (elem->data, 1, j),
1871 XVECEXP (subst_elem->data, 1, j),
1872 subst_elem->loc))
1874 patterns_match = 0;
1875 break;
1878 if (!get_alternatives_number (XVECEXP (elem->data, 1, j),
1879 &alternatives, subst_elem->loc))
1881 patterns_match = 0;
1882 break;
1886 /* Check if numbers of alternatives are the same in all
1887 match_operands in output template of define_subst. */
1888 for (j = 0; j < XVECLEN (subst_elem->data, 3); j++)
1890 if (!get_alternatives_number (XVECEXP (subst_elem->data, 3, j),
1891 &alternatives_subst,
1892 subst_elem->loc))
1894 patterns_match = 0;
1895 break;
1899 if (!patterns_match)
1900 continue;
1902 /* Clear array in which we save occupied indexes of operands. */
1903 memset (used_operands_numbers, 0, sizeof (used_operands_numbers));
1905 /* Create a pattern, based on the output one from define_subst. */
1906 subst_pattern_vec = rtvec_alloc (XVECLEN (subst_elem->data, 3));
1907 for (j = 0; j < XVECLEN (subst_elem->data, 3); j++)
1909 subst_pattern = copy_rtx (XVECEXP (subst_elem->data, 3, j));
1911 /* Duplicate constraints in substitute-pattern. */
1912 subst_pattern = alter_constraints (subst_pattern, alternatives,
1913 duplicate_each_alternative);
1915 subst_pattern = adjust_operands_numbers (subst_pattern);
1917 /* Substitute match_dup and match_op_dup in the new pattern and
1918 duplicate constraints. */
1919 subst_pattern = subst_dup (subst_pattern, alternatives,
1920 alternatives_subst);
1922 replace_duplicating_operands_in_pattern (subst_pattern);
1924 /* We don't need any constraints in DEFINE_EXPAND. */
1925 if (GET_CODE (elem->data) == DEFINE_EXPAND)
1926 remove_constraints (subst_pattern);
1928 RTVEC_ELT (subst_pattern_vec, j) = subst_pattern;
1930 XVEC (elem->data, 1) = subst_pattern_vec;
1932 for (i = 0; i < MAX_OPERANDS; i++)
1933 match_operand_entries_in_pattern[i] = NULL;
1935 if (GET_CODE (elem->data) == DEFINE_INSN)
1937 XTMPL (elem->data, 3) =
1938 alter_output_for_subst_insn (elem->data, alternatives_subst);
1939 alter_attrs_for_subst_insn (elem, alternatives_subst);
1942 /* Recalculate condition, joining conditions from original and
1943 DEFINE_SUBST input patterns. */
1944 XSTR (elem->data, 2)
1945 = rtx_reader_ptr->join_c_conditions (XSTR (subst_elem->data, 2),
1946 XSTR (elem->data, 2));
1947 /* Mark that subst was applied by changing attribute from "yes"
1948 to "no". */
1949 change_subst_attribute (elem, subst_elem, subst_false);
1952 /* If ELEM contains a subst attribute with value "yes", then we
1953 expected that a subst would be applied, but it wasn't - so,
1954 we need to remove that elementto avoid duplicating. */
1955 for (subst_elem = define_subst_queue;
1956 subst_elem; subst_elem = subst_elem->next)
1958 if (has_subst_attribute (elem, subst_elem))
1960 remove_from_queue (elem, &queue);
1961 return;
1966 /* This is a subroutine of mark_operands_used_in_match_dup.
1967 This routine is marks all MATCH_OPERANDs inside PATTERN as occupied. */
1968 static void
1969 mark_operands_from_match_dup (rtx pattern)
1971 const char *fmt;
1972 int i, j, len, opno;
1974 if (GET_CODE (pattern) == MATCH_OPERAND
1975 || GET_CODE (pattern) == MATCH_OPERATOR
1976 || GET_CODE (pattern) == MATCH_PARALLEL)
1978 opno = XINT (pattern, 0);
1979 gcc_assert (opno >= 0 && opno < MAX_OPERANDS);
1980 used_operands_numbers [opno] = 1;
1982 fmt = GET_RTX_FORMAT (GET_CODE (pattern));
1983 len = GET_RTX_LENGTH (GET_CODE (pattern));
1984 for (i = 0; i < len; i++)
1986 switch (fmt[i])
1988 case 'e': case 'u':
1989 mark_operands_from_match_dup (XEXP (pattern, i));
1990 break;
1991 case 'E':
1992 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
1993 mark_operands_from_match_dup (XVECEXP (pattern, i, j));
1994 break;
1999 /* This is a subroutine of adjust_operands_numbers.
2000 It goes through all expressions in PATTERN and when MATCH_DUP is
2001 met, all MATCH_OPERANDs inside it is marked as occupied. The
2002 process of marking is done by routin mark_operands_from_match_dup. */
2003 static void
2004 mark_operands_used_in_match_dup (rtx pattern)
2006 const char *fmt;
2007 int i, j, len, opno;
2009 if (GET_CODE (pattern) == MATCH_DUP)
2011 opno = XINT (pattern, 0);
2012 gcc_assert (opno >= 0 && opno < MAX_OPERANDS);
2013 mark_operands_from_match_dup (operand_data[opno]);
2014 return;
2016 fmt = GET_RTX_FORMAT (GET_CODE (pattern));
2017 len = GET_RTX_LENGTH (GET_CODE (pattern));
2018 for (i = 0; i < len; i++)
2020 switch (fmt[i])
2022 case 'e': case 'u':
2023 mark_operands_used_in_match_dup (XEXP (pattern, i));
2024 break;
2025 case 'E':
2026 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
2027 mark_operands_used_in_match_dup (XVECEXP (pattern, i, j));
2028 break;
2033 /* This is subroutine of renumerate_operands_in_pattern.
2034 It finds first not-occupied operand-index. */
2035 static int
2036 find_first_unused_number_of_operand ()
2038 int i;
2039 for (i = 0; i < MAX_OPERANDS; i++)
2040 if (!used_operands_numbers[i])
2041 return i;
2042 return MAX_OPERANDS;
2045 /* This is subroutine of adjust_operands_numbers.
2046 It visits all expressions in PATTERN and assigns not-occupied
2047 operand indexes to MATCH_OPERANDs and MATCH_OPERATORs of this
2048 PATTERN. */
2049 static void
2050 renumerate_operands_in_pattern (rtx pattern)
2052 const char *fmt;
2053 enum rtx_code code;
2054 int i, j, len, new_opno;
2055 code = GET_CODE (pattern);
2057 if (code == MATCH_OPERAND
2058 || code == MATCH_OPERATOR)
2060 new_opno = find_first_unused_number_of_operand ();
2061 gcc_assert (new_opno >= 0 && new_opno < MAX_OPERANDS);
2062 XINT (pattern, 0) = new_opno;
2063 used_operands_numbers [new_opno] = 1;
2066 fmt = GET_RTX_FORMAT (GET_CODE (pattern));
2067 len = GET_RTX_LENGTH (GET_CODE (pattern));
2068 for (i = 0; i < len; i++)
2070 switch (fmt[i])
2072 case 'e': case 'u':
2073 renumerate_operands_in_pattern (XEXP (pattern, i));
2074 break;
2075 case 'E':
2076 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
2077 renumerate_operands_in_pattern (XVECEXP (pattern, i, j));
2078 break;
2083 /* If output pattern of define_subst contains MATCH_DUP, then this
2084 expression would be replaced with the pattern, matched with
2085 MATCH_OPERAND from input pattern. This pattern could contain any
2086 number of MATCH_OPERANDs, MATCH_OPERATORs etc., so it's possible
2087 that a MATCH_OPERAND from output_pattern (if any) would have the
2088 same number, as MATCH_OPERAND from copied pattern. To avoid such
2089 indexes overlapping, we assign new indexes to MATCH_OPERANDs,
2090 laying in the output pattern outside of MATCH_DUPs. */
2091 static rtx
2092 adjust_operands_numbers (rtx pattern)
2094 mark_operands_used_in_match_dup (pattern);
2096 renumerate_operands_in_pattern (pattern);
2098 return pattern;
2101 /* Generate RTL expression
2102 (match_dup OPNO)
2104 static rtx
2105 generate_match_dup (int opno)
2107 rtx return_rtx = rtx_alloc (MATCH_DUP);
2108 PUT_CODE (return_rtx, MATCH_DUP);
2109 XINT (return_rtx, 0) = opno;
2110 return return_rtx;
2113 /* This routine checks all match_operands in PATTERN and if some of
2114 have the same index, it replaces all of them except the first one to
2115 match_dup.
2116 Usually, match_operands with the same indexes are forbidden, but
2117 after define_subst copy an RTL-expression from original template,
2118 indexes of existed and just-copied match_operands could coincide.
2119 To fix it, we replace one of them with match_dup. */
2120 static rtx
2121 replace_duplicating_operands_in_pattern (rtx pattern)
2123 const char *fmt;
2124 int i, j, len, opno;
2125 rtx mdup;
2127 if (GET_CODE (pattern) == MATCH_OPERAND)
2129 opno = XINT (pattern, 0);
2130 gcc_assert (opno >= 0 && opno < MAX_OPERANDS);
2131 if (match_operand_entries_in_pattern[opno] == NULL)
2133 match_operand_entries_in_pattern[opno] = pattern;
2134 return NULL;
2136 else
2138 /* Compare predicates before replacing with match_dup. */
2139 if (strcmp (XSTR (pattern, 1),
2140 XSTR (match_operand_entries_in_pattern[opno], 1)))
2142 error ("duplicated match_operands with different predicates were"
2143 " found.");
2144 return NULL;
2146 return generate_match_dup (opno);
2149 fmt = GET_RTX_FORMAT (GET_CODE (pattern));
2150 len = GET_RTX_LENGTH (GET_CODE (pattern));
2151 for (i = 0; i < len; i++)
2153 switch (fmt[i])
2155 case 'e': case 'u':
2156 mdup = replace_duplicating_operands_in_pattern (XEXP (pattern, i));
2157 if (mdup)
2158 XEXP (pattern, i) = mdup;
2159 break;
2160 case 'E':
2161 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
2163 mdup =
2164 replace_duplicating_operands_in_pattern (XVECEXP
2165 (pattern, i, j));
2166 if (mdup)
2167 XVECEXP (pattern, i, j) = mdup;
2169 break;
2172 return NULL;
2175 /* The routine modifies given input PATTERN of define_subst, replacing
2176 MATCH_DUP and MATCH_OP_DUP with operands from define_insn original
2177 pattern, whose operands are stored in OPERAND_DATA array.
2178 It also duplicates constraints in operands - constraints from
2179 define_insn operands are duplicated N_SUBST_ALT times, constraints
2180 from define_subst operands are duplicated N_ALT times.
2181 After the duplication, returned output rtl-pattern contains every
2182 combination of input constraints Vs constraints from define_subst
2183 output. */
2184 static rtx
2185 subst_dup (rtx pattern, int n_alt, int n_subst_alt)
2187 const char *fmt;
2188 enum rtx_code code;
2189 int i, j, len, opno;
2191 code = GET_CODE (pattern);
2192 switch (code)
2194 case MATCH_DUP:
2195 case MATCH_OP_DUP:
2196 opno = XINT (pattern, 0);
2198 gcc_assert (opno >= 0 && opno < MAX_OPERANDS);
2200 if (operand_data[opno])
2202 pattern = copy_rtx (operand_data[opno]);
2204 /* Duplicate constraints. */
2205 pattern = alter_constraints (pattern, n_subst_alt,
2206 duplicate_alternatives);
2208 break;
2210 default:
2211 break;
2214 fmt = GET_RTX_FORMAT (GET_CODE (pattern));
2215 len = GET_RTX_LENGTH (GET_CODE (pattern));
2216 for (i = 0; i < len; i++)
2218 switch (fmt[i])
2220 case 'e': case 'u':
2221 if (code != MATCH_DUP && code != MATCH_OP_DUP)
2222 XEXP (pattern, i) = subst_dup (XEXP (pattern, i),
2223 n_alt, n_subst_alt);
2224 break;
2225 case 'V':
2226 if (XVEC (pattern, i) == NULL)
2227 break;
2228 /* FALLTHRU */
2229 case 'E':
2230 if (code != MATCH_DUP && code != MATCH_OP_DUP)
2231 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
2232 XVECEXP (pattern, i, j) = subst_dup (XVECEXP (pattern, i, j),
2233 n_alt, n_subst_alt);
2234 break;
2236 case 'r': case 'p': case 'i': case 'w':
2237 case '0': case 's': case 'S': case 'T':
2238 break;
2240 default:
2241 gcc_unreachable ();
2244 return pattern;
2247 /* If we have any DEFINE_COND_EXEC patterns, expand the DEFINE_INSN
2248 patterns appropriately. */
2250 static void
2251 process_define_cond_exec (void)
2253 class queue_elem *elem;
2255 identify_predicable_attribute ();
2256 if (have_error)
2257 return;
2259 for (elem = define_cond_exec_queue; elem ; elem = elem->next)
2260 process_one_cond_exec (elem);
2263 /* If we have any DEFINE_SUBST patterns, expand DEFINE_INSN and
2264 DEFINE_EXPAND patterns appropriately. */
2266 static void
2267 process_define_subst (void)
2269 class queue_elem *elem, *elem_attr;
2271 /* Check if each define_subst has corresponding define_subst_attr. */
2272 for (elem = define_subst_queue; elem ; elem = elem->next)
2274 for (elem_attr = define_subst_attr_queue;
2275 elem_attr;
2276 elem_attr = elem_attr->next)
2277 if (strcmp (XSTR (elem->data, 0), XSTR (elem_attr->data, 1)) == 0)
2278 goto found;
2280 error_at (elem->loc,
2281 "%s: `define_subst' must have at least one "
2282 "corresponding `define_subst_attr'",
2283 XSTR (elem->data, 0));
2284 return;
2286 found:
2287 continue;
2290 for (elem = define_insn_queue; elem ; elem = elem->next)
2291 process_substs_on_one_elem (elem, define_insn_queue);
2292 for (elem = other_queue; elem ; elem = elem->next)
2294 if (GET_CODE (elem->data) != DEFINE_EXPAND)
2295 continue;
2296 process_substs_on_one_elem (elem, other_queue);
2300 /* A subclass of rtx_reader which reads .md files and calls process_rtx on
2301 the top-level elements. */
2303 class gen_reader : public rtx_reader
2305 public:
2306 gen_reader () : rtx_reader (false) {}
2307 void handle_unknown_directive (file_location, const char *);
2310 void
2311 gen_reader::handle_unknown_directive (file_location loc, const char *rtx_name)
2313 auto_vec<rtx, 32> subrtxs;
2314 if (!read_rtx (rtx_name, &subrtxs))
2315 return;
2317 rtx x;
2318 unsigned int i;
2319 FOR_EACH_VEC_ELT (subrtxs, i, x)
2320 process_rtx (x, loc);
2323 /* Comparison function for the mnemonic hash table. */
2325 static int
2326 htab_eq_string (const void *s1, const void *s2)
2328 return strcmp ((const char*)s1, (const char*)s2) == 0;
2331 /* Add mnemonic STR with length LEN to the mnemonic hash table
2332 MNEMONIC_HTAB. A trailing zero end character is appended to STR
2333 and a permanent heap copy of STR is created. */
2335 static void
2336 add_mnemonic_string (htab_t mnemonic_htab, const char *str, size_t len)
2338 char *new_str;
2339 void **slot;
2340 char *str_zero = (char*)alloca (len + 1);
2342 memcpy (str_zero, str, len);
2343 str_zero[len] = '\0';
2345 slot = htab_find_slot (mnemonic_htab, str_zero, INSERT);
2347 if (*slot)
2348 return;
2350 /* Not found; create a permanent copy and add it to the hash table. */
2351 new_str = XNEWVAR (char, len + 1);
2352 memcpy (new_str, str_zero, len + 1);
2353 *slot = new_str;
2356 /* Scan INSN for mnemonic strings and add them to the mnemonic hash
2357 table in MNEMONIC_HTAB.
2359 The mnemonics cannot be found if they are emitted using C code.
2361 If a mnemonic string contains ';' or a newline the string assumed
2362 to consist of more than a single instruction. The attribute value
2363 will then be set to the user defined default value. */
2365 static void
2366 gen_mnemonic_setattr (htab_t mnemonic_htab, rtx insn)
2368 const char *template_code, *cp;
2369 int i;
2370 int vec_len;
2371 rtx set_attr;
2372 char *attr_name;
2373 rtvec new_vec;
2374 struct obstack *string_obstack = rtx_reader_ptr->get_string_obstack ();
2376 template_code = XTMPL (insn, 3);
2378 /* Skip patterns which use C code to emit the template. */
2379 if (template_code[0] == '*')
2380 return;
2382 if (template_code[0] == '@')
2383 cp = &template_code[1];
2384 else
2385 cp = &template_code[0];
2387 for (i = 0; *cp; )
2389 const char *ep, *sp;
2390 size_t size = 0;
2392 while (ISSPACE (*cp))
2393 cp++;
2395 for (ep = sp = cp; !IS_VSPACE (*ep) && *ep != '\0'; ++ep)
2396 if (!ISSPACE (*ep))
2397 sp = ep + 1;
2399 if (i > 0)
2400 obstack_1grow (string_obstack, ',');
2402 while (cp < sp && ((*cp >= '0' && *cp <= '9')
2403 || (*cp >= 'a' && *cp <= 'z')))
2406 obstack_1grow (string_obstack, *cp);
2407 cp++;
2408 size++;
2411 while (cp < sp)
2413 if (*cp == ';' || (*cp == '\\' && cp[1] == 'n'))
2415 /* Don't set a value if there are more than one
2416 instruction in the string. */
2417 obstack_blank_fast (string_obstack, -size);
2418 size = 0;
2420 cp = sp;
2421 break;
2423 cp++;
2425 if (size == 0)
2426 obstack_1grow (string_obstack, '*');
2427 else
2428 add_mnemonic_string (mnemonic_htab,
2429 (char *) obstack_next_free (string_obstack) - size,
2430 size);
2431 i++;
2434 /* An insn definition might emit an empty string. */
2435 if (obstack_object_size (string_obstack) == 0)
2436 return;
2438 obstack_1grow (string_obstack, '\0');
2440 set_attr = rtx_alloc (SET_ATTR);
2441 XSTR (set_attr, 1) = XOBFINISH (string_obstack, char *);
2442 attr_name = XNEWVAR (char, strlen (MNEMONIC_ATTR_NAME) + 1);
2443 strcpy (attr_name, MNEMONIC_ATTR_NAME);
2444 XSTR (set_attr, 0) = attr_name;
2446 if (!XVEC (insn, 4))
2447 vec_len = 0;
2448 else
2449 vec_len = XVECLEN (insn, 4);
2451 new_vec = rtvec_alloc (vec_len + 1);
2452 for (i = 0; i < vec_len; i++)
2453 RTVEC_ELT (new_vec, i) = XVECEXP (insn, 4, i);
2454 RTVEC_ELT (new_vec, vec_len) = set_attr;
2455 XVEC (insn, 4) = new_vec;
2458 /* This function is called for the elements in the mnemonic hashtable
2459 and generates a comma separated list of the mnemonics. */
2461 static int
2462 mnemonic_htab_callback (void **slot, void *info ATTRIBUTE_UNUSED)
2464 struct obstack *string_obstack = rtx_reader_ptr->get_string_obstack ();
2466 obstack_grow (string_obstack, (char*) *slot, strlen ((char*) *slot));
2467 obstack_1grow (string_obstack, ',');
2468 return 1;
2471 /* Generate (set_attr "mnemonic" "..") RTXs and append them to every
2472 insn definition in case the back end requests it by defining the
2473 mnemonic attribute. The values for the attribute will be extracted
2474 from the output patterns of the insn definitions as far as
2475 possible. */
2477 static void
2478 gen_mnemonic_attr (void)
2480 class queue_elem *elem;
2481 rtx mnemonic_attr = NULL;
2482 htab_t mnemonic_htab;
2483 const char *str, *p;
2484 int i;
2485 struct obstack *string_obstack = rtx_reader_ptr->get_string_obstack ();
2487 if (have_error)
2488 return;
2490 /* Look for the DEFINE_ATTR for `mnemonic'. */
2491 for (elem = define_attr_queue; elem != *define_attr_tail; elem = elem->next)
2492 if (GET_CODE (elem->data) == DEFINE_ATTR
2493 && strcmp (XSTR (elem->data, 0), MNEMONIC_ATTR_NAME) == 0)
2495 mnemonic_attr = elem->data;
2496 break;
2499 /* A (define_attr "mnemonic" "...") indicates that the back-end
2500 wants a mnemonic attribute to be generated. */
2501 if (!mnemonic_attr)
2502 return;
2504 mnemonic_htab = htab_create_alloc (MNEMONIC_HTAB_SIZE, htab_hash_string,
2505 htab_eq_string, 0, xcalloc, free);
2507 for (elem = define_insn_queue; elem; elem = elem->next)
2509 rtx insn = elem->data;
2510 bool found = false;
2512 /* Check if the insn definition already has
2513 (set_attr "mnemonic" ...) or (set (attr "mnemonic") ...). */
2514 if (XVEC (insn, 4))
2515 for (i = 0; i < XVECLEN (insn, 4); i++)
2517 rtx set_attr = XVECEXP (insn, 4, i);
2519 switch (GET_CODE (set_attr))
2521 case SET_ATTR:
2522 case SET_ATTR_ALTERNATIVE:
2523 if (strcmp (XSTR (set_attr, 0), MNEMONIC_ATTR_NAME) == 0)
2524 found = true;
2525 break;
2526 case SET:
2527 if (GET_CODE (SET_DEST (set_attr)) == ATTR
2528 && strcmp (XSTR (SET_DEST (set_attr), 0),
2529 MNEMONIC_ATTR_NAME) == 0)
2530 found = true;
2531 break;
2532 default:
2533 break;
2537 if (!found)
2538 gen_mnemonic_setattr (mnemonic_htab, insn);
2541 /* Add the user defined values to the hash table. */
2542 str = XSTR (mnemonic_attr, 1);
2543 while ((p = scan_comma_elt (&str)) != NULL)
2544 add_mnemonic_string (mnemonic_htab, p, str - p);
2546 htab_traverse (mnemonic_htab, mnemonic_htab_callback, NULL);
2548 /* Replace the last ',' with the zero end character. */
2549 *((char *) obstack_next_free (string_obstack) - 1) = '\0';
2550 XSTR (mnemonic_attr, 1) = XOBFINISH (string_obstack, char *);
2553 /* Check if there are DEFINE_ATTRs with the same name. */
2554 static void
2555 check_define_attr_duplicates ()
2557 class queue_elem *elem;
2558 htab_t attr_htab;
2559 char * attr_name;
2560 void **slot;
2562 attr_htab = htab_create (500, htab_hash_string, htab_eq_string, NULL);
2564 for (elem = define_attr_queue; elem; elem = elem->next)
2566 attr_name = xstrdup (XSTR (elem->data, 0));
2568 slot = htab_find_slot (attr_htab, attr_name, INSERT);
2570 /* Duplicate. */
2571 if (*slot)
2573 error_at (elem->loc, "redefinition of attribute '%s'", attr_name);
2574 htab_delete (attr_htab);
2575 return;
2578 *slot = attr_name;
2581 htab_delete (attr_htab);
2584 /* The entry point for initializing the reader. */
2586 rtx_reader *
2587 init_rtx_reader_args_cb (int argc, const char **argv,
2588 bool (*parse_opt) (const char *))
2590 /* Prepare to read input. */
2591 condition_table = htab_create (500, hash_c_test, cmp_c_test, NULL);
2592 init_predicate_table ();
2593 obstack_init (rtl_obstack);
2595 /* Start at 1, to make 0 available for CODE_FOR_nothing. */
2596 insn_sequence_num = 1;
2598 /* These sequences are not used as indices, so can start at 1 also. */
2599 split_sequence_num = 1;
2600 peephole2_sequence_num = 1;
2602 gen_reader *reader = new gen_reader ();
2603 reader->read_md_files (argc, argv, parse_opt);
2605 if (define_attr_queue != NULL)
2606 check_define_attr_duplicates ();
2608 /* Process define_cond_exec patterns. */
2609 if (define_cond_exec_queue != NULL)
2610 process_define_cond_exec ();
2612 /* Process define_subst patterns. */
2613 if (define_subst_queue != NULL)
2614 process_define_subst ();
2616 if (define_attr_queue != NULL)
2617 gen_mnemonic_attr ();
2619 if (have_error)
2621 delete reader;
2622 return NULL;
2625 return reader;
2628 /* Programs that don't have their own options can use this entry point
2629 instead. */
2630 rtx_reader *
2631 init_rtx_reader_args (int argc, const char **argv)
2633 return init_rtx_reader_args_cb (argc, argv, 0);
2636 /* Try to read a single rtx from the file. Return true on success,
2637 describing it in *INFO. */
2639 bool
2640 read_md_rtx (md_rtx_info *info)
2642 int truth, *counter;
2643 rtx def;
2645 /* Discard insn patterns which we know can never match (because
2646 their C test is provably always false). If insn_elision is
2647 false, our caller needs to see all the patterns. Note that the
2648 elided patterns are never counted by the sequence numbering; it
2649 is the caller's responsibility, when insn_elision is false, not
2650 to use elided pattern numbers for anything. */
2653 class queue_elem **queue, *elem;
2655 /* Read all patterns from a given queue before moving on to the next. */
2656 if (define_attr_queue != NULL)
2657 queue = &define_attr_queue;
2658 else if (define_pred_queue != NULL)
2659 queue = &define_pred_queue;
2660 else if (define_insn_queue != NULL)
2661 queue = &define_insn_queue;
2662 else if (other_queue != NULL)
2663 queue = &other_queue;
2664 else
2665 return false;
2667 elem = *queue;
2668 *queue = elem->next;
2669 def = elem->data;
2670 info->def = def;
2671 info->loc = elem->loc;
2672 free (elem);
2674 truth = maybe_eval_c_test (get_c_test (def));
2676 while (truth == 0 && insn_elision);
2678 /* Perform code-specific processing and pick the appropriate sequence
2679 number counter. */
2680 switch (GET_CODE (def))
2682 case DEFINE_INSN:
2683 case DEFINE_EXPAND:
2684 /* insn_sequence_num is used here so the name table will match caller's
2685 idea of insn numbering, whether or not elision is active. */
2686 record_insn_name (insn_sequence_num, XSTR (def, 0));
2688 /* Fall through. */
2689 case DEFINE_PEEPHOLE:
2690 counter = &insn_sequence_num;
2691 break;
2693 case DEFINE_SPLIT:
2694 counter = &split_sequence_num;
2695 break;
2697 case DEFINE_PEEPHOLE2:
2698 counter = &peephole2_sequence_num;
2699 break;
2701 default:
2702 counter = NULL;
2703 break;
2706 if (counter)
2708 info->index = *counter;
2709 if (truth != 0)
2710 *counter += 1;
2712 else
2713 info->index = -1;
2715 if (!rtx_locs)
2716 rtx_locs = new hash_map <rtx, file_location>;
2717 rtx_locs->put (info->def, info->loc);
2719 return true;
2722 /* Return the file location of DEFINE_* rtx X, which was previously
2723 returned by read_md_rtx. */
2724 file_location
2725 get_file_location (rtx x)
2727 gcc_assert (rtx_locs);
2728 file_location *entry = rtx_locs->get (x);
2729 gcc_assert (entry);
2730 return *entry;
2733 /* Return the number of possible INSN_CODEs. Only meaningful once the
2734 whole file has been processed. */
2735 unsigned int
2736 get_num_insn_codes ()
2738 return insn_sequence_num;
2741 /* Return the C test that says whether definition rtx DEF can be used,
2742 or "" if it can be used unconditionally. */
2744 const char *
2745 get_c_test (rtx x)
2747 switch (GET_CODE (x))
2749 case DEFINE_INSN:
2750 case DEFINE_EXPAND:
2751 case DEFINE_SUBST:
2752 return XSTR (x, 2);
2754 case DEFINE_SPLIT:
2755 case DEFINE_PEEPHOLE:
2756 case DEFINE_PEEPHOLE2:
2757 return XSTR (x, 1);
2759 default:
2760 return "";
2764 /* Helper functions for insn elision. */
2766 /* Compute a hash function of a c_test structure, which is keyed
2767 by its ->expr field. */
2768 hashval_t
2769 hash_c_test (const void *x)
2771 const struct c_test *a = (const struct c_test *) x;
2772 const unsigned char *base, *s = (const unsigned char *) a->expr;
2773 hashval_t hash;
2774 unsigned char c;
2775 unsigned int len;
2777 base = s;
2778 hash = 0;
2780 while ((c = *s++) != '\0')
2782 hash += c + (c << 17);
2783 hash ^= hash >> 2;
2786 len = s - base;
2787 hash += len + (len << 17);
2788 hash ^= hash >> 2;
2790 return hash;
2793 /* Compare two c_test expression structures. */
2795 cmp_c_test (const void *x, const void *y)
2797 const struct c_test *a = (const struct c_test *) x;
2798 const struct c_test *b = (const struct c_test *) y;
2800 return !strcmp (a->expr, b->expr);
2803 /* Given a string representing a C test expression, look it up in the
2804 condition_table and report whether or not its value is known
2805 at compile time. Returns a tristate: 1 for known true, 0 for
2806 known false, -1 for unknown. */
2808 maybe_eval_c_test (const char *expr)
2810 const struct c_test *test;
2811 struct c_test dummy;
2813 if (expr[0] == 0)
2814 return 1;
2816 dummy.expr = expr;
2817 test = (const struct c_test *)htab_find (condition_table, &dummy);
2818 if (!test)
2819 return -1;
2820 return test->value;
2823 /* Record the C test expression EXPR in the condition_table, with
2824 value VAL. Duplicates clobber previous entries. */
2826 void
2827 add_c_test (const char *expr, int value)
2829 struct c_test *test;
2831 if (expr[0] == 0)
2832 return;
2834 test = XNEW (struct c_test);
2835 test->expr = expr;
2836 test->value = value;
2838 *(htab_find_slot (condition_table, test, INSERT)) = test;
2841 /* For every C test, call CALLBACK with two arguments: a pointer to
2842 the condition structure and INFO. Stops when CALLBACK returns zero. */
2843 void
2844 traverse_c_tests (htab_trav callback, void *info)
2846 if (condition_table)
2847 htab_traverse (condition_table, callback, info);
2850 /* Helper functions for define_predicate and define_special_predicate
2851 processing. Shared between genrecog.c and genpreds.c. */
2853 static htab_t predicate_table;
2854 struct pred_data *first_predicate;
2855 static struct pred_data **last_predicate = &first_predicate;
2857 static hashval_t
2858 hash_struct_pred_data (const void *ptr)
2860 return htab_hash_string (((const struct pred_data *)ptr)->name);
2863 static int
2864 eq_struct_pred_data (const void *a, const void *b)
2866 return !strcmp (((const struct pred_data *)a)->name,
2867 ((const struct pred_data *)b)->name);
2870 struct pred_data *
2871 lookup_predicate (const char *name)
2873 struct pred_data key;
2874 key.name = name;
2875 return (struct pred_data *) htab_find (predicate_table, &key);
2878 /* Record that predicate PRED can accept CODE. */
2880 void
2881 add_predicate_code (struct pred_data *pred, enum rtx_code code)
2883 if (!pred->codes[code])
2885 pred->num_codes++;
2886 pred->codes[code] = true;
2888 if (GET_RTX_CLASS (code) != RTX_CONST_OBJ)
2889 pred->allows_non_const = true;
2891 if (code != REG
2892 && code != SUBREG
2893 && code != MEM
2894 && code != CONCAT
2895 && code != PARALLEL
2896 && code != STRICT_LOW_PART
2897 && code != ZERO_EXTRACT
2898 && code != SCRATCH)
2899 pred->allows_non_lvalue = true;
2901 if (pred->num_codes == 1)
2902 pred->singleton = code;
2903 else if (pred->num_codes == 2)
2904 pred->singleton = UNKNOWN;
2908 void
2909 add_predicate (struct pred_data *pred)
2911 void **slot = htab_find_slot (predicate_table, pred, INSERT);
2912 if (*slot)
2914 error ("duplicate predicate definition for '%s'", pred->name);
2915 return;
2917 *slot = pred;
2918 *last_predicate = pred;
2919 last_predicate = &pred->next;
2922 /* This array gives the initial content of the predicate table. It
2923 has entries for all predicates defined in recog.c. */
2925 struct std_pred_table
2927 const char *name;
2928 bool special;
2929 bool allows_const_p;
2930 RTX_CODE codes[NUM_RTX_CODE];
2933 static const struct std_pred_table std_preds[] = {
2934 {"general_operand", false, true, {SUBREG, REG, MEM}},
2935 {"address_operand", true, true, {SUBREG, REG, MEM, PLUS, MINUS, MULT,
2936 ZERO_EXTEND, SIGN_EXTEND, AND}},
2937 {"register_operand", false, false, {SUBREG, REG}},
2938 {"pmode_register_operand", true, false, {SUBREG, REG}},
2939 {"scratch_operand", false, false, {SCRATCH, REG}},
2940 {"immediate_operand", false, true, {UNKNOWN}},
2941 {"const_int_operand", false, false, {CONST_INT}},
2942 #if TARGET_SUPPORTS_WIDE_INT
2943 {"const_scalar_int_operand", false, false, {CONST_INT, CONST_WIDE_INT}},
2944 {"const_double_operand", false, false, {CONST_DOUBLE}},
2945 #else
2946 {"const_double_operand", false, false, {CONST_INT, CONST_DOUBLE}},
2947 #endif
2948 {"nonimmediate_operand", false, false, {SUBREG, REG, MEM}},
2949 {"nonmemory_operand", false, true, {SUBREG, REG}},
2950 {"push_operand", false, false, {MEM}},
2951 {"pop_operand", false, false, {MEM}},
2952 {"memory_operand", false, false, {SUBREG, MEM}},
2953 {"indirect_operand", false, false, {SUBREG, MEM}},
2954 {"ordered_comparison_operator", false, false, {EQ, NE,
2955 LE, LT, GE, GT,
2956 LEU, LTU, GEU, GTU}},
2957 {"comparison_operator", false, false, {EQ, NE,
2958 LE, LT, GE, GT,
2959 LEU, LTU, GEU, GTU,
2960 UNORDERED, ORDERED,
2961 UNEQ, UNGE, UNGT,
2962 UNLE, UNLT, LTGT}}
2964 #define NUM_KNOWN_STD_PREDS ARRAY_SIZE (std_preds)
2966 /* Initialize the table of predicate definitions, starting with
2967 the information we have on generic predicates. */
2969 static void
2970 init_predicate_table (void)
2972 size_t i, j;
2973 struct pred_data *pred;
2975 predicate_table = htab_create_alloc (37, hash_struct_pred_data,
2976 eq_struct_pred_data, 0,
2977 xcalloc, free);
2979 for (i = 0; i < NUM_KNOWN_STD_PREDS; i++)
2981 pred = XCNEW (struct pred_data);
2982 pred->name = std_preds[i].name;
2983 pred->special = std_preds[i].special;
2985 for (j = 0; std_preds[i].codes[j] != 0; j++)
2986 add_predicate_code (pred, std_preds[i].codes[j]);
2988 if (std_preds[i].allows_const_p)
2989 for (j = 0; j < NUM_RTX_CODE; j++)
2990 if (GET_RTX_CLASS (j) == RTX_CONST_OBJ)
2991 add_predicate_code (pred, (enum rtx_code) j);
2993 add_predicate (pred);
2997 /* These functions allow linkage with print-rtl.c. Also, some generators
2998 like to annotate their output with insn names. */
3000 /* Holds an array of names indexed by insn_code_number. */
3001 static char **insn_name_ptr = 0;
3002 static int insn_name_ptr_size = 0;
3004 const char *
3005 get_insn_name (int code)
3007 if (code < insn_name_ptr_size)
3008 return insn_name_ptr[code];
3009 else
3010 return NULL;
3013 static void
3014 record_insn_name (int code, const char *name)
3016 static const char *last_real_name = "insn";
3017 static int last_real_code = 0;
3018 char *new_name;
3020 if (insn_name_ptr_size <= code)
3022 int new_size;
3023 new_size = (insn_name_ptr_size ? insn_name_ptr_size * 2 : 512);
3024 insn_name_ptr = XRESIZEVEC (char *, insn_name_ptr, new_size);
3025 memset (insn_name_ptr + insn_name_ptr_size, 0,
3026 sizeof (char *) * (new_size - insn_name_ptr_size));
3027 insn_name_ptr_size = new_size;
3030 if (!name || name[0] == '\0')
3032 new_name = XNEWVAR (char, strlen (last_real_name) + 10);
3033 sprintf (new_name, "%s+%d", last_real_name, code - last_real_code);
3035 else
3037 last_real_name = new_name = xstrdup (name);
3038 last_real_code = code;
3041 insn_name_ptr[code] = new_name;
3044 /* Make STATS describe the operands that appear in rtx X. */
3046 static void
3047 get_pattern_stats_1 (struct pattern_stats *stats, rtx x)
3049 RTX_CODE code;
3050 int i;
3051 int len;
3052 const char *fmt;
3054 if (x == NULL_RTX)
3055 return;
3057 code = GET_CODE (x);
3058 switch (code)
3060 case MATCH_OPERAND:
3061 case MATCH_OPERATOR:
3062 case MATCH_PARALLEL:
3063 stats->max_opno = MAX (stats->max_opno, XINT (x, 0));
3064 break;
3066 case MATCH_DUP:
3067 case MATCH_OP_DUP:
3068 case MATCH_PAR_DUP:
3069 stats->num_dups++;
3070 stats->max_dup_opno = MAX (stats->max_dup_opno, XINT (x, 0));
3071 break;
3073 case MATCH_SCRATCH:
3074 if (stats->min_scratch_opno == -1)
3075 stats->min_scratch_opno = XINT (x, 0);
3076 else
3077 stats->min_scratch_opno = MIN (stats->min_scratch_opno, XINT (x, 0));
3078 stats->max_scratch_opno = MAX (stats->max_scratch_opno, XINT (x, 0));
3079 break;
3081 default:
3082 break;
3085 fmt = GET_RTX_FORMAT (code);
3086 len = GET_RTX_LENGTH (code);
3087 for (i = 0; i < len; i++)
3089 if (fmt[i] == 'e' || fmt[i] == 'u')
3090 get_pattern_stats_1 (stats, XEXP (x, i));
3091 else if (fmt[i] == 'E')
3093 int j;
3094 for (j = 0; j < XVECLEN (x, i); j++)
3095 get_pattern_stats_1 (stats, XVECEXP (x, i, j));
3100 /* Make STATS describe the operands that appear in instruction pattern
3101 PATTERN. */
3103 void
3104 get_pattern_stats (struct pattern_stats *stats, rtvec pattern)
3106 int i, len;
3108 stats->max_opno = -1;
3109 stats->max_dup_opno = -1;
3110 stats->min_scratch_opno = -1;
3111 stats->max_scratch_opno = -1;
3112 stats->num_dups = 0;
3114 len = GET_NUM_ELEM (pattern);
3115 for (i = 0; i < len; i++)
3116 get_pattern_stats_1 (stats, RTVEC_ELT (pattern, i));
3118 stats->num_generator_args = stats->max_opno + 1;
3119 stats->num_insn_operands = MAX (stats->max_opno,
3120 stats->max_scratch_opno) + 1;
3121 stats->num_operand_vars = MAX (stats->max_opno,
3122 MAX (stats->max_dup_opno,
3123 stats->max_scratch_opno)) + 1;
3126 /* Return the emit_* function that should be used for pattern X, or NULL
3127 if we can't pick a particular type at compile time and should instead
3128 fall back to "emit". */
3130 const char *
3131 get_emit_function (rtx x)
3133 switch (classify_insn (x))
3135 case INSN:
3136 return "emit_insn";
3138 case CALL_INSN:
3139 return "emit_call_insn";
3141 case JUMP_INSN:
3142 return "emit_jump_insn";
3144 case UNKNOWN:
3145 return NULL;
3147 default:
3148 gcc_unreachable ();
3152 /* Return true if we must emit a barrier after pattern X. */
3154 bool
3155 needs_barrier_p (rtx x)
3157 return (GET_CODE (x) == SET
3158 && GET_CODE (SET_DEST (x)) == PC
3159 && GET_CODE (SET_SRC (x)) == LABEL_REF);
3162 #define NS "NULL"
3163 #define ZS "'\\0'"
3164 #define OPTAB_CL(o, p, c, b, l) { #o, p, #b, ZS, #l, o, c, UNKNOWN, 1 },
3165 #define OPTAB_CX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 1 },
3166 #define OPTAB_CD(o, p) { #o, p, NS, ZS, NS, o, UNKNOWN, UNKNOWN, 2 },
3167 #define OPTAB_NL(o, p, c, b, s, l) { #o, p, #b, #s, #l, o, c, c, 3 },
3168 #define OPTAB_NC(o, p, c) { #o, p, NS, ZS, NS, o, c, c, 3 },
3169 #define OPTAB_NX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 3 },
3170 #define OPTAB_VL(o, p, c, b, s, l) { #o, p, #b, #s, #l, o, c, UNKNOWN, 3 },
3171 #define OPTAB_VC(o, p, c) { #o, p, NS, ZS, NS, o, c, UNKNOWN, 3 },
3172 #define OPTAB_VX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 3 },
3173 #define OPTAB_DC(o, p, c) { #o, p, NS, ZS, NS, o, c, c, 4 },
3174 #define OPTAB_D(o, p) { #o, p, NS, ZS, NS, o, UNKNOWN, UNKNOWN, 4 },
3176 /* An array of all optabs. Note that the same optab can appear more
3177 than once, with a different pattern. */
3178 optab_def optabs[] = {
3179 { "unknown_optab", NULL, NS, ZS, NS, unknown_optab, UNKNOWN, UNKNOWN, 0 },
3180 #include "optabs.def"
3183 /* The number of entries in optabs[]. */
3184 unsigned int num_optabs = ARRAY_SIZE (optabs);
3186 #undef OPTAB_CL
3187 #undef OPTAB_CX
3188 #undef OPTAB_CD
3189 #undef OPTAB_NL
3190 #undef OPTAB_NC
3191 #undef OPTAB_NX
3192 #undef OPTAB_VL
3193 #undef OPTAB_VC
3194 #undef OPTAB_VX
3195 #undef OPTAB_DC
3196 #undef OPTAB_D
3198 /* Return true if instruction NAME matches pattern PAT, storing information
3199 about the match in P if so. */
3201 static bool
3202 match_pattern (optab_pattern *p, const char *name, const char *pat)
3204 bool force_float = false;
3205 bool force_int = false;
3206 bool force_partial_int = false;
3207 bool force_fixed = false;
3209 if (pat == NULL)
3210 return false;
3211 for (; ; ++pat)
3213 if (*pat != '$')
3215 if (*pat != *name++)
3216 return false;
3217 if (*pat == '\0')
3218 return true;
3219 continue;
3221 switch (*++pat)
3223 case 'I':
3224 force_int = 1;
3225 break;
3226 case 'P':
3227 force_partial_int = 1;
3228 break;
3229 case 'F':
3230 force_float = 1;
3231 break;
3232 case 'Q':
3233 force_fixed = 1;
3234 break;
3236 case 'a':
3237 case 'b':
3239 int i;
3241 /* This loop will stop at the first prefix match, so
3242 look through the modes in reverse order, in case
3243 there are extra CC modes and CC is a prefix of the
3244 CC modes (as it should be). */
3245 for (i = (MAX_MACHINE_MODE) - 1; i >= 0; i--)
3247 const char *p, *q;
3248 for (p = GET_MODE_NAME (i), q = name; *p; p++, q++)
3249 if (TOLOWER (*p) != *q)
3250 break;
3251 if (*p == 0
3252 && (! force_int || mode_class[i] == MODE_INT
3253 || mode_class[i] == MODE_VECTOR_INT)
3254 && (! force_partial_int
3255 || mode_class[i] == MODE_INT
3256 || mode_class[i] == MODE_PARTIAL_INT
3257 || mode_class[i] == MODE_VECTOR_INT)
3258 && (! force_float
3259 || mode_class[i] == MODE_FLOAT
3260 || mode_class[i] == MODE_DECIMAL_FLOAT
3261 || mode_class[i] == MODE_COMPLEX_FLOAT
3262 || mode_class[i] == MODE_VECTOR_FLOAT)
3263 && (! force_fixed
3264 || mode_class[i] == MODE_FRACT
3265 || mode_class[i] == MODE_UFRACT
3266 || mode_class[i] == MODE_ACCUM
3267 || mode_class[i] == MODE_UACCUM
3268 || mode_class[i] == MODE_VECTOR_FRACT
3269 || mode_class[i] == MODE_VECTOR_UFRACT
3270 || mode_class[i] == MODE_VECTOR_ACCUM
3271 || mode_class[i] == MODE_VECTOR_UACCUM))
3272 break;
3275 if (i < 0)
3276 return false;
3277 name += strlen (GET_MODE_NAME (i));
3278 if (*pat == 'a')
3279 p->m1 = i;
3280 else
3281 p->m2 = i;
3283 force_int = false;
3284 force_partial_int = false;
3285 force_float = false;
3286 force_fixed = false;
3288 break;
3290 default:
3291 gcc_unreachable ();
3296 /* Return true if NAME is the name of an optab, describing it in P if so. */
3298 bool
3299 find_optab (optab_pattern *p, const char *name)
3301 if (*name == 0 || *name == '*')
3302 return false;
3304 /* See if NAME matches one of the patterns we have for the optabs
3305 we know about. */
3306 for (unsigned int pindex = 0; pindex < ARRAY_SIZE (optabs); pindex++)
3308 p->m1 = p->m2 = 0;
3309 if (match_pattern (p, name, optabs[pindex].pattern))
3311 p->name = name;
3312 p->op = optabs[pindex].op;
3313 p->sort_num = (p->op << 16) | (p->m2 << 8) | p->m1;
3314 return true;
3317 return false;