Use strtol instead of std::stoi [PR110646]
[official-gcc.git] / gcc / gensupport.cc
blobf7164b3214d210c99cc11f7bc71096cd8a6987e1
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 #define INCLUDE_STRING
22 #define INCLUDE_VECTOR
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "rtl.h"
27 #include "obstack.h"
28 #include "errors.h"
29 #include "read-md.h"
30 #include "gensupport.h"
31 #include "vec.h"
33 #define MAX_OPERANDS 40
35 static rtx operand_data[MAX_OPERANDS];
36 static rtx match_operand_entries_in_pattern[MAX_OPERANDS];
37 static char used_operands_numbers[MAX_OPERANDS];
38 /* List of entries which are part of the new syntax. */
39 hash_set<rtx> compact_syntax;
42 /* In case some macros used by files we include need it, define this here. */
43 int target_flags;
45 int insn_elision = 1;
47 static struct obstack obstack;
48 struct obstack *rtl_obstack = &obstack;
50 /* Counter for named patterns and INSN_CODEs. */
51 static int insn_sequence_num;
53 /* Counter for define_splits. */
54 static int split_sequence_num;
56 /* Counter for define_peephole2s. */
57 static int peephole2_sequence_num;
59 static int predicable_default;
60 static const char *predicable_true;
61 static const char *predicable_false;
63 static const char *subst_true = "yes";
64 static const char *subst_false = "no";
66 static htab_t condition_table;
68 /* We initially queue all patterns, process the define_insn,
69 define_cond_exec and define_subst patterns, then return
70 them one at a time. */
72 class queue_elem
74 public:
75 rtx data;
76 file_location loc;
77 class queue_elem *next;
78 /* In a DEFINE_INSN that came from a DEFINE_INSN_AND_SPLIT or
79 DEFINE_INSN_AND_REWRITE, SPLIT points to the generated DEFINE_SPLIT. */
80 class queue_elem *split;
83 #define MNEMONIC_ATTR_NAME "mnemonic"
84 #define MNEMONIC_HTAB_SIZE 1024
86 static class queue_elem *define_attr_queue;
87 static class queue_elem **define_attr_tail = &define_attr_queue;
88 static class queue_elem *define_pred_queue;
89 static class queue_elem **define_pred_tail = &define_pred_queue;
90 static class queue_elem *define_insn_queue;
91 static class queue_elem **define_insn_tail = &define_insn_queue;
92 static class queue_elem *define_cond_exec_queue;
93 static class queue_elem **define_cond_exec_tail = &define_cond_exec_queue;
94 static class queue_elem *define_subst_queue;
95 static class queue_elem **define_subst_tail = &define_subst_queue;
96 static class queue_elem *other_queue;
97 static class queue_elem **other_tail = &other_queue;
98 static class queue_elem *define_subst_attr_queue;
99 static class queue_elem **define_subst_attr_tail = &define_subst_attr_queue;
101 /* Mapping from DEFINE_* rtxes to their location in the source file. */
102 static hash_map <rtx, file_location> *rtx_locs;
104 static void remove_constraints (rtx);
106 static int is_predicable (class queue_elem *);
107 static void identify_predicable_attribute (void);
108 static int n_alternatives (const char *);
109 static void collect_insn_data (rtx, int *, int *);
110 static const char *alter_test_for_insn (class queue_elem *,
111 class queue_elem *);
112 static char *shift_output_template (char *, const char *, int);
113 static const char *alter_output_for_insn (class queue_elem *,
114 class queue_elem *,
115 int, int);
116 static void process_one_cond_exec (class queue_elem *);
117 static void process_define_cond_exec (void);
118 static void init_predicate_table (void);
119 static void record_insn_name (int, const char *);
121 static bool has_subst_attribute (class queue_elem *, class queue_elem *);
122 static const char * alter_output_for_subst_insn (rtx, int);
123 static void alter_attrs_for_subst_insn (class queue_elem *, int);
124 static void process_substs_on_one_elem (class queue_elem *,
125 class queue_elem *);
126 static rtx subst_dup (rtx, int, int);
127 static void process_define_subst (void);
129 static const char * duplicate_alternatives (const char *, int);
130 static const char * duplicate_each_alternative (const char * str, int n_dup);
132 typedef const char * (*constraints_handler_t) (const char *, int);
133 static rtx alter_constraints (rtx, int, constraints_handler_t);
134 static rtx adjust_operands_numbers (rtx);
135 static rtx replace_duplicating_operands_in_pattern (rtx);
137 /* Make a version of gen_rtx_CONST_INT so that GEN_INT can be used in
138 the gensupport programs. */
141 gen_rtx_CONST_INT (machine_mode ARG_UNUSED (mode),
142 HOST_WIDE_INT arg)
144 rtx rt = rtx_alloc (CONST_INT);
146 XWINT (rt, 0) = arg;
147 return rt;
150 /* Return the rtx pattern specified by the list of rtxes in a
151 define_insn or define_split. */
154 add_implicit_parallel (rtvec vec)
156 if (GET_NUM_ELEM (vec) == 1)
157 return RTVEC_ELT (vec, 0);
158 else
160 rtx pattern = rtx_alloc (PARALLEL);
161 XVEC (pattern, 0) = vec;
162 return pattern;
166 /* Predicate handling.
168 We construct from the machine description a table mapping each
169 predicate to a list of the rtl codes it can possibly match. The
170 function 'maybe_both_true' uses it to deduce that there are no
171 expressions that can be matches by certain pairs of tree nodes.
172 Also, if a predicate can match only one code, we can hardwire that
173 code into the node testing the predicate.
175 Some predicates are flagged as special. validate_pattern will not
176 warn about modeless match_operand expressions if they have a
177 special predicate. Predicates that allow only constants are also
178 treated as special, for this purpose.
180 validate_pattern will warn about predicates that allow non-lvalues
181 when they appear in destination operands.
183 Calculating the set of rtx codes that can possibly be accepted by a
184 predicate expression EXP requires a three-state logic: any given
185 subexpression may definitively accept a code C (Y), definitively
186 reject a code C (N), or may have an indeterminate effect (I). N
187 and I is N; Y or I is Y; Y and I, N or I are both I. Here are full
188 truth tables.
190 a b a&b a|b
191 Y Y Y Y
192 N Y N Y
193 N N N N
194 I Y I Y
195 I N N I
196 I I I I
198 We represent Y with 1, N with 0, I with 2. If any code is left in
199 an I state by the complete expression, we must assume that that
200 code can be accepted. */
202 #define N 0
203 #define Y 1
204 #define I 2
206 #define TRISTATE_AND(a,b) \
207 ((a) == I ? ((b) == N ? N : I) : \
208 (b) == I ? ((a) == N ? N : I) : \
209 (a) && (b))
211 #define TRISTATE_OR(a,b) \
212 ((a) == I ? ((b) == Y ? Y : I) : \
213 (b) == I ? ((a) == Y ? Y : I) : \
214 (a) || (b))
216 #define TRISTATE_NOT(a) \
217 ((a) == I ? I : !(a))
219 /* 0 means no warning about that code yet, 1 means warned. */
220 static char did_you_mean_codes[NUM_RTX_CODE];
222 /* Recursively calculate the set of rtx codes accepted by the
223 predicate expression EXP, writing the result to CODES. LOC is
224 the .md file location of the directive containing EXP. */
226 void
227 compute_test_codes (rtx exp, file_location loc, char *codes)
229 char op0_codes[NUM_RTX_CODE];
230 char op1_codes[NUM_RTX_CODE];
231 char op2_codes[NUM_RTX_CODE];
232 int i;
234 switch (GET_CODE (exp))
236 case AND:
237 compute_test_codes (XEXP (exp, 0), loc, op0_codes);
238 compute_test_codes (XEXP (exp, 1), loc, op1_codes);
239 for (i = 0; i < NUM_RTX_CODE; i++)
240 codes[i] = TRISTATE_AND (op0_codes[i], op1_codes[i]);
241 break;
243 case IOR:
244 compute_test_codes (XEXP (exp, 0), loc, op0_codes);
245 compute_test_codes (XEXP (exp, 1), loc, op1_codes);
246 for (i = 0; i < NUM_RTX_CODE; i++)
247 codes[i] = TRISTATE_OR (op0_codes[i], op1_codes[i]);
248 break;
249 case NOT:
250 compute_test_codes (XEXP (exp, 0), loc, op0_codes);
251 for (i = 0; i < NUM_RTX_CODE; i++)
252 codes[i] = TRISTATE_NOT (op0_codes[i]);
253 break;
255 case IF_THEN_ELSE:
256 /* a ? b : c accepts the same codes as (a & b) | (!a & c). */
257 compute_test_codes (XEXP (exp, 0), loc, op0_codes);
258 compute_test_codes (XEXP (exp, 1), loc, op1_codes);
259 compute_test_codes (XEXP (exp, 2), loc, op2_codes);
260 for (i = 0; i < NUM_RTX_CODE; i++)
261 codes[i] = TRISTATE_OR (TRISTATE_AND (op0_codes[i], op1_codes[i]),
262 TRISTATE_AND (TRISTATE_NOT (op0_codes[i]),
263 op2_codes[i]));
264 break;
266 case MATCH_CODE:
267 /* MATCH_CODE allows a specified list of codes. However, if it
268 does not apply to the top level of the expression, it does not
269 constrain the set of codes for the top level. */
270 if (XSTR (exp, 1)[0] != '\0')
272 memset (codes, Y, NUM_RTX_CODE);
273 break;
276 memset (codes, N, NUM_RTX_CODE);
278 const char *next_code = XSTR (exp, 0);
279 const char *code;
281 if (*next_code == '\0')
283 error_at (loc, "empty match_code expression");
284 break;
287 while ((code = scan_comma_elt (&next_code)) != 0)
289 size_t n = next_code - code;
290 int found_it = 0;
292 for (i = 0; i < NUM_RTX_CODE; i++)
293 if (!strncmp (code, GET_RTX_NAME (i), n)
294 && GET_RTX_NAME (i)[n] == '\0')
296 codes[i] = Y;
297 found_it = 1;
298 break;
300 if (!found_it)
302 error_at (loc, "match_code \"%.*s\" matches nothing",
303 (int) n, code);
304 for (i = 0; i < NUM_RTX_CODE; i++)
305 if (!strncasecmp (code, GET_RTX_NAME (i), n)
306 && GET_RTX_NAME (i)[n] == '\0'
307 && !did_you_mean_codes[i])
309 did_you_mean_codes[i] = 1;
310 message_at (loc, "(did you mean \"%s\"?)",
311 GET_RTX_NAME (i));
316 break;
318 case MATCH_OPERAND:
319 /* MATCH_OPERAND disallows the set of codes that the named predicate
320 disallows, and is indeterminate for the codes that it does allow. */
322 struct pred_data *p = lookup_predicate (XSTR (exp, 1));
323 if (!p)
325 error_at (loc, "reference to unknown predicate '%s'",
326 XSTR (exp, 1));
327 break;
329 for (i = 0; i < NUM_RTX_CODE; i++)
330 codes[i] = p->codes[i] ? I : N;
332 break;
335 case MATCH_TEST:
336 /* (match_test WHATEVER) is completely indeterminate. */
337 memset (codes, I, NUM_RTX_CODE);
338 break;
340 default:
341 error_at (loc, "'%s' cannot be used in predicates or constraints",
342 GET_RTX_NAME (GET_CODE (exp)));
343 memset (codes, I, NUM_RTX_CODE);
344 break;
348 #undef TRISTATE_OR
349 #undef TRISTATE_AND
350 #undef TRISTATE_NOT
352 /* Return true if NAME is a valid predicate name. */
354 static bool
355 valid_predicate_name_p (const char *name)
357 const char *p;
359 if (!ISALPHA (name[0]) && name[0] != '_')
360 return false;
361 for (p = name + 1; *p; p++)
362 if (!ISALNUM (*p) && *p != '_')
363 return false;
364 return true;
367 /* Process define_predicate directive DESC, which appears at location LOC.
368 Compute the set of codes that can be matched, and record this as a known
369 predicate. */
371 static void
372 process_define_predicate (rtx desc, file_location loc)
374 struct pred_data *pred;
375 char codes[NUM_RTX_CODE];
376 int i;
378 if (!valid_predicate_name_p (XSTR (desc, 0)))
380 error_at (loc, "%s: predicate name must be a valid C function name",
381 XSTR (desc, 0));
382 return;
385 pred = XCNEW (struct pred_data);
386 pred->name = XSTR (desc, 0);
387 pred->exp = XEXP (desc, 1);
388 pred->c_block = XSTR (desc, 2);
389 if (GET_CODE (desc) == DEFINE_SPECIAL_PREDICATE)
390 pred->special = true;
392 compute_test_codes (XEXP (desc, 1), loc, codes);
394 for (i = 0; i < NUM_RTX_CODE; i++)
395 if (codes[i] != N)
396 add_predicate_code (pred, (enum rtx_code) i);
398 add_predicate (pred);
400 #undef I
401 #undef N
402 #undef Y
404 /* Queue PATTERN on LIST_TAIL. Return the address of the new queue
405 element. */
407 static class queue_elem *
408 queue_pattern (rtx pattern, class queue_elem ***list_tail,
409 file_location loc)
411 class queue_elem *e = XNEW (class queue_elem);
412 e->data = pattern;
413 e->loc = loc;
414 e->next = NULL;
415 e->split = NULL;
416 **list_tail = e;
417 *list_tail = &e->next;
418 return e;
421 /* Remove element ELEM from QUEUE. */
422 static void
423 remove_from_queue (class queue_elem *elem, class queue_elem **queue)
425 class queue_elem *prev, *e;
426 prev = NULL;
427 for (e = *queue; e ; e = e->next)
429 if (e == elem)
430 break;
431 prev = e;
433 if (e == NULL)
434 return;
436 if (prev)
437 prev->next = elem->next;
438 else
439 *queue = elem->next;
442 /* Build a define_attr for an binary attribute with name NAME and
443 possible values "yes" and "no", and queue it. */
444 static void
445 add_define_attr (const char *name)
447 class queue_elem *e = XNEW (class queue_elem);
448 rtx t1 = rtx_alloc (DEFINE_ATTR);
449 XSTR (t1, 0) = name;
450 XSTR (t1, 1) = "no,yes";
451 XEXP (t1, 2) = rtx_alloc (CONST_STRING);
452 XSTR (XEXP (t1, 2), 0) = "yes";
453 e->data = t1;
454 e->loc = file_location ("built-in", -1, -1);
455 e->next = define_attr_queue;
456 define_attr_queue = e;
460 /* Recursively remove constraints from an rtx. */
462 static void
463 remove_constraints (rtx part)
465 int i, j;
466 const char *format_ptr;
468 if (part == 0)
469 return;
471 if (GET_CODE (part) == MATCH_OPERAND)
472 XSTR (part, 2) = "";
473 else if (GET_CODE (part) == MATCH_SCRATCH)
474 XSTR (part, 1) = "";
476 format_ptr = GET_RTX_FORMAT (GET_CODE (part));
478 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
479 switch (*format_ptr++)
481 case 'e':
482 case 'u':
483 remove_constraints (XEXP (part, i));
484 break;
485 case 'E':
486 if (XVEC (part, i) != NULL)
487 for (j = 0; j < XVECLEN (part, i); j++)
488 remove_constraints (XVECEXP (part, i, j));
489 break;
493 /* Recursively replace MATCH_OPERANDs with MATCH_DUPs and MATCH_OPERATORs
494 with MATCH_OP_DUPs in X. */
496 static rtx
497 replace_operands_with_dups (rtx x)
499 if (x == 0)
500 return x;
502 rtx newx;
503 if (GET_CODE (x) == MATCH_OPERAND)
505 newx = rtx_alloc (MATCH_DUP);
506 XINT (newx, 0) = XINT (x, 0);
507 x = newx;
509 else if (GET_CODE (x) == MATCH_OPERATOR)
511 newx = rtx_alloc (MATCH_OP_DUP);
512 XINT (newx, 0) = XINT (x, 0);
513 XVEC (newx, 1) = XVEC (x, 2);
514 x = newx;
516 else
517 newx = shallow_copy_rtx (x);
519 const char *format_ptr = GET_RTX_FORMAT (GET_CODE (x));
520 for (int i = 0; i < GET_RTX_LENGTH (GET_CODE (x)); i++)
521 switch (*format_ptr++)
523 case 'e':
524 case 'u':
525 XEXP (newx, i) = replace_operands_with_dups (XEXP (x, i));
526 break;
527 case 'E':
528 if (XVEC (x, i) != NULL)
530 XVEC (newx, i) = rtvec_alloc (XVECLEN (x, i));
531 for (int j = 0; j < XVECLEN (x, i); j++)
532 XVECEXP (newx, i, j)
533 = replace_operands_with_dups (XVECEXP (x, i, j));
535 break;
537 return newx;
540 /* Convert matching pattern VEC from a DEFINE_INSN_AND_REWRITE into
541 a sequence that should be generated by the splitter. */
543 static rtvec
544 gen_rewrite_sequence (rtvec vec)
546 rtvec new_vec = rtvec_alloc (1);
547 rtx x = add_implicit_parallel (vec);
548 RTVEC_ELT (new_vec, 0) = replace_operands_with_dups (x);
549 return new_vec;
552 /* The following is for handling the compact syntax for constraints and
553 attributes.
555 The normal syntax looks like this:
558 (match_operand: 0 "s_register_operand" "r,I,k")
559 (match_operand: 2 "s_register_operand" "r,k,I")
562 <asm>
563 <asm>
564 <asm>"
566 (set_attr "length" "4,8,8")
568 The compact syntax looks like this:
571 (match_operand: 0 "s_register_operand")
572 (match_operand: 2 "s_register_operand")
574 {@ [cons: 0, 2; attrs: length]
575 [r,r; 4] <asm>
576 [I,k; 8] <asm>
577 [k,I; 8] <asm>
580 [<other attributes>]
582 This is the only place where this syntax needs to be handled. Relevant
583 patterns are transformed from compact to the normal syntax before they are
584 queued, so none of the gen* programs need to know about this syntax at all.
586 Conversion process (convert_syntax):
588 0) Check that pattern actually uses new syntax (check for {@ ... }).
590 1) Get the "layout", i.e. the "[cons: 0 2; attrs: length]" from the above
591 example. cons must come first; both are optional. Set up two vecs,
592 convec and attrvec, for holding the results of the transformation.
594 2) For each alternative: parse the list of constraints and/or attributes,
595 and enqueue them in the relevant lists in convec and attrvec. By the end
596 of this process, convec[N].con and attrvec[N].con should contain regular
597 syntax constraint/attribute lists like "r,I,k". Copy the asm to a string
598 as we go.
600 3) Search the rtx and write the constraint and attribute lists into the
601 correct places. Write the asm back into the template. */
603 /* Helper class for shuffling constraints/attributes in convert_syntax and
604 add_constraints/add_attributes. This includes commas but not whitespace. */
606 class conlist {
607 private:
608 std::string con;
610 public:
611 std::string name;
612 int idx = -1;
614 conlist () = default;
616 /* [ns..ns + len) should be a string with the id of the rtx to match
617 i.e. if rtx is the relevant match_operand or match_scratch then
618 [ns..ns + len) should equal itoa (XINT (rtx, 0)), and if set_attr then
619 [ns..ns + len) should equal XSTR (rtx, 0). */
620 conlist (const char *ns, unsigned int len, bool numeric)
622 /* Trim leading whitespaces. */
623 while (len > 0 && ISBLANK (*ns))
625 ns++;
626 len--;
629 /* Trim trailing whitespace. */
630 for (int i = len - 1; i >= 0; i--, len--)
631 if (!ISBLANK (ns[i]))
632 break;
634 /* Parse off any modifiers. */
635 while (len > 0 && !ISALNUM (*ns))
637 con += *(ns++);
638 len--;
641 name.assign (ns, len);
642 if (numeric)
643 idx = strtol (name.c_str (), (char **)NULL, 10);
646 /* Adds a character to the end of the string. */
647 void add (char c)
649 con += c;
652 /* Output the string in the form of a brand-new char *, then effectively
653 clear the internal string by resetting len to 0. */
654 char *out ()
656 /* Final character is always a trailing comma, so strip it out. */
657 char *q = xstrndup (con.c_str (), con.size () - 1);
658 con.clear ();
659 return q;
663 typedef std::vector<conlist> vec_conlist;
665 /* Add constraints to an rtx. This function is similar to remove_constraints.
666 Errors if adding the constraints would overwrite existing constraints. */
668 static void
669 add_constraints (rtx part, file_location loc, vec_conlist &cons)
671 const char *format_ptr;
673 if (part == NULL_RTX)
674 return;
676 /* If match_op or match_scr, check if we have the right one, and if so, copy
677 over the constraint list. */
678 if (GET_CODE (part) == MATCH_OPERAND || GET_CODE (part) == MATCH_SCRATCH)
680 int field = GET_CODE (part) == MATCH_OPERAND ? 2 : 1;
681 unsigned id = XINT (part, 0);
683 if (id >= cons.size () || cons[id].idx == -1)
684 return;
686 if (XSTR (part, field)[0] != '\0')
688 error_at (loc, "can't mix normal and compact constraint syntax");
689 return;
691 XSTR (part, field) = cons[id].out ();
692 cons[id].idx = -1;
695 format_ptr = GET_RTX_FORMAT (GET_CODE (part));
697 /* Recursively search the rtx. */
698 for (int i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
699 switch (*format_ptr++)
701 case 'e':
702 case 'u':
703 add_constraints (XEXP (part, i), loc, cons);
704 break;
705 case 'E':
706 if (XVEC (part, i) != NULL)
707 for (int j = 0; j < XVECLEN (part, i); j++)
708 add_constraints (XVECEXP (part, i, j), loc, cons);
709 break;
710 default:
711 continue;
715 /* Add ATTRS to definition X's attribute list. */
717 static void
718 add_attributes (rtx x, vec_conlist &attrs)
720 unsigned int attr_index = GET_CODE (x) == DEFINE_INSN ? 4 : 3;
721 rtvec orig = XVEC (x, attr_index);
722 if (orig)
724 size_t n_curr = XVECLEN (x, attr_index);
725 rtvec copy = rtvec_alloc (n_curr + attrs.size ());
727 /* Create a shallow copy of existing entries. */
728 memcpy (&copy->elem[attrs.size ()], &orig->elem[0],
729 sizeof (rtx) * n_curr);
730 XVEC (x, attr_index) = copy;
732 else
733 XVEC (x, attr_index) = rtvec_alloc (attrs.size ());
735 /* Create the new elements. */
736 for (unsigned i = 0; i < attrs.size (); i++)
738 rtx attr = rtx_alloc (SET_ATTR);
739 XSTR (attr, 0) = xstrdup (attrs[i].name.c_str ());
740 XSTR (attr, 1) = attrs[i].out ();
741 XVECEXP (x, attr_index, i) = attr;
745 /* Consumes spaces and tabs. */
747 static inline void
748 skip_spaces (const char **str)
750 while (ISBLANK (**str))
751 (*str)++;
754 /* Consumes the given character, if it's there. */
756 static inline bool
757 expect_char (const char **str, char c)
759 if (**str != c)
760 return false;
761 (*str)++;
762 return true;
765 /* Parses the section layout that follows a "{@" if using new syntax. Builds
766 a vector for a single section. E.g. if we have "attrs: length, arch]..."
767 then list will have two elements, the first for "length" and the second
768 for "arch". */
770 static void
771 parse_section_layout (file_location loc, const char **templ, const char *label,
772 vec_conlist &list, bool numeric)
774 const char *name_start;
775 size_t label_len = strlen (label);
776 if (strncmp (label, *templ, label_len) == 0)
778 *templ += label_len;
780 /* Gather the names. */
781 while (**templ != ';' && **templ != ']')
783 skip_spaces (templ);
784 name_start = *templ;
785 int len = 0;
786 char val = (*templ)[len];
787 while (val != ',' && val != ';' && val != ']')
789 if (val == 0 || val == '\n')
790 fatal_at (loc, "missing ']'");
791 val = (*templ)[++len];
793 *templ += len;
794 if (val == ',')
795 (*templ)++;
796 list.push_back (conlist (name_start, len, numeric));
801 /* Parse a section, a section is defined as a named space separated list, e.g.
803 foo: a, b, c
805 is a section named "foo" with entries a, b and c. */
807 static void
808 parse_section (const char **templ, unsigned int n_elems, unsigned int alt_no,
809 vec_conlist &list, file_location loc, const char *name)
811 unsigned int i;
813 /* Go through the list, one character at a time, adding said character
814 to the correct string. */
815 for (i = 0; **templ != ']' && **templ != ';'; (*templ)++)
816 if (!ISBLANK (**templ))
818 if (**templ == 0 || **templ == '\n')
819 fatal_at (loc, "missing ']'");
820 list[i].add (**templ);
821 if (**templ == ',')
823 ++i;
824 if (i == n_elems)
825 fatal_at (loc, "too many %ss in alternative %d: expected %d",
826 name, alt_no, n_elems);
830 if (i + 1 < n_elems)
831 fatal_at (loc, "too few %ss in alternative %d: expected %d, got %d",
832 name, alt_no, n_elems, i);
834 list[i].add (',');
837 /* The compact syntax has more convience syntaxes. As such we post process
838 the lines to get them back to something the normal syntax understands. */
840 static void
841 preprocess_compact_syntax (file_location loc, int alt_no, std::string &line,
842 std::string &last_line)
844 /* Check if we're copying the last statement. */
845 if (line.find ("^") == 0 && line.size () == 1)
847 if (last_line.empty ())
848 fatal_at (loc, "found instruction to copy previous line (^) in"
849 "alternative %d but no previous line to copy", alt_no);
850 line = last_line;
851 return;
854 std::string result;
855 std::string buffer;
856 /* Check if we have << which means return c statement. */
857 if (line.find ("<<") == 0)
859 result.append ("* return ");
860 const char *chunk = line.c_str () + 2;
861 skip_spaces (&chunk);
862 result.append (chunk);
864 else
865 result.append (line);
867 line = result;
868 return;
871 /* Converts an rtx from compact syntax to normal syntax if possible. */
873 static void
874 convert_syntax (rtx x, file_location loc)
876 int alt_no;
877 unsigned int templ_index;
878 const char *templ;
879 vec_conlist tconvec, convec, attrvec;
881 templ_index = 3;
882 gcc_assert (GET_CODE (x) == DEFINE_INSN);
884 templ = XTMPL (x, templ_index);
886 /* Templates with constraints start with "{@". */
887 if (strncmp ("*{@", templ, 3))
888 return;
890 /* Get the layout for the template. */
891 templ += 3;
892 skip_spaces (&templ);
894 if (!expect_char (&templ, '['))
895 fatal_at (loc, "expecing `[' to begin section list");
897 parse_section_layout (loc, &templ, "cons:", tconvec, true);
899 /* Check for any duplicate cons entries and sort based on i. */
900 for (auto e : tconvec)
902 unsigned idx = e.idx;
903 if (idx >= convec.size ())
904 convec.resize (idx + 1);
906 if (convec[idx].idx >= 0)
907 fatal_at (loc, "duplicate cons number found: %d", idx);
908 convec[idx] = e;
910 tconvec.clear ();
912 if (*templ != ']')
914 if (*templ == ';')
915 skip_spaces (&(++templ));
916 parse_section_layout (loc, &templ, "attrs:", attrvec, false);
919 if (!expect_char (&templ, ']'))
920 fatal_at (loc, "expecting `]` to end section list - section list must have "
921 "cons first, attrs second");
923 /* We will write the un-constrainified template into new_templ. */
924 std::string new_templ;
925 new_templ.append ("@");
927 /* Skip to the first proper line. */
928 skip_spaces (&templ);
929 if (*templ == 0)
930 fatal_at (loc, "'{@...}' blocks must have at least one alternative");
931 if (*templ != '\n')
932 fatal_at (loc, "unexpected character '%c' after ']'", *templ);
933 templ++;
935 alt_no = 0;
936 std::string last_line;
938 /* Process the alternatives. */
939 while (*(templ - 1) != '\0')
941 /* Skip leading whitespace. */
942 std::string buffer;
943 skip_spaces (&templ);
945 /* Check if we're at the end. */
946 if (templ[0] == '}' && templ[1] == '\0')
947 break;
949 if (expect_char (&templ, '['))
951 new_templ += '\n';
952 new_templ.append (buffer);
953 /* Parse the constraint list, then the attribute list. */
954 if (convec.size () > 0)
955 parse_section (&templ, convec.size (), alt_no, convec, loc,
956 "constraint");
958 if (attrvec.size () > 0)
960 if (convec.size () > 0 && !expect_char (&templ, ';'))
961 fatal_at (loc, "expected `;' to separate constraints "
962 "and attributes in alternative %d", alt_no);
964 parse_section (&templ, attrvec.size (), alt_no,
965 attrvec, loc, "attribute");
968 if (!expect_char (&templ, ']'))
969 fatal_at (loc, "expected end of constraint/attribute list but "
970 "missing an ending `]' in alternative %d", alt_no);
972 else if (templ[0] == '/' && templ[1] == '/')
974 templ += 2;
975 /* Glob till newline or end of string. */
976 while (*templ != '\n' || *templ != '\0')
977 templ++;
979 /* Skip any newlines or whitespaces needed. */
980 while (ISSPACE(*templ))
981 templ++;
982 continue;
984 else if (templ[0] == '/' && templ[1] == '*')
986 templ += 2;
987 /* Glob till newline or end of multiline comment. */
988 while (templ[0] != 0 && templ[0] != '*' && templ[1] != '/')
989 templ++;
991 while (templ[0] != '*' || templ[1] != '/')
993 if (templ[0] == 0)
994 fatal_at (loc, "unterminated '/*'");
995 templ++;
997 templ += 2;
999 /* Skip any newlines or whitespaces needed. */
1000 while (ISSPACE(*templ))
1001 templ++;
1002 continue;
1004 else
1005 fatal_at (loc, "expected constraint/attribute list at beginning of "
1006 "alternative %d but missing a starting `['", alt_no);
1008 /* Skip whitespace between list and asm. */
1009 skip_spaces (&templ);
1011 /* Copy asm to new template. */
1012 std::string line;
1013 while (*templ != '\n' && *templ != '\0')
1014 line += *templ++;
1016 /* Apply any pre-processing needed to the line. */
1017 preprocess_compact_syntax (loc, alt_no, line, last_line);
1018 new_templ.append (line);
1019 last_line = line;
1021 /* Normal "*..." syntax expects the closing quote to be on the final
1022 line of asm, whereas we allow the closing "}" to be on its own line.
1023 Postpone copying the '\n' until we know that there is another
1024 alternative in the list. */
1025 while (ISSPACE (*templ))
1026 templ++;
1027 ++alt_no;
1030 /* Write the constraints and attributes into their proper places. */
1031 if (convec.size () > 0)
1032 add_constraints (x, loc, convec);
1034 if (attrvec.size () > 0)
1035 add_attributes (x, attrvec);
1037 /* Copy over the new un-constrainified template. */
1038 XTMPL (x, templ_index) = xstrdup (new_templ.c_str ());
1040 /* Register for later checks during iterator expansions. */
1041 compact_syntax.add (x);
1044 /* Process a top level rtx in some way, queuing as appropriate. */
1046 static void
1047 process_rtx (rtx desc, file_location loc)
1049 switch (GET_CODE (desc))
1051 case DEFINE_INSN:
1052 convert_syntax (desc, loc);
1053 queue_pattern (desc, &define_insn_tail, loc);
1054 break;
1056 case DEFINE_COND_EXEC:
1057 queue_pattern (desc, &define_cond_exec_tail, loc);
1058 break;
1060 case DEFINE_SUBST:
1061 queue_pattern (desc, &define_subst_tail, loc);
1062 break;
1064 case DEFINE_SUBST_ATTR:
1065 queue_pattern (desc, &define_subst_attr_tail, loc);
1066 break;
1068 case DEFINE_ATTR:
1069 case DEFINE_ENUM_ATTR:
1070 queue_pattern (desc, &define_attr_tail, loc);
1071 break;
1073 case DEFINE_PREDICATE:
1074 case DEFINE_SPECIAL_PREDICATE:
1075 process_define_predicate (desc, loc);
1076 /* Fall through. */
1078 case DEFINE_CONSTRAINT:
1079 case DEFINE_REGISTER_CONSTRAINT:
1080 case DEFINE_MEMORY_CONSTRAINT:
1081 case DEFINE_SPECIAL_MEMORY_CONSTRAINT:
1082 case DEFINE_RELAXED_MEMORY_CONSTRAINT:
1083 case DEFINE_ADDRESS_CONSTRAINT:
1084 queue_pattern (desc, &define_pred_tail, loc);
1085 break;
1087 case DEFINE_INSN_AND_SPLIT:
1088 case DEFINE_INSN_AND_REWRITE:
1090 const char *split_cond;
1091 rtx split;
1092 rtvec attr;
1093 int i;
1094 class queue_elem *insn_elem;
1095 class queue_elem *split_elem;
1096 int split_code = (GET_CODE (desc) == DEFINE_INSN_AND_REWRITE ? 5 : 6);
1098 /* Create a split with values from the insn_and_split. */
1099 split = rtx_alloc (DEFINE_SPLIT);
1101 i = XVECLEN (desc, 1);
1102 XVEC (split, 0) = rtvec_alloc (i);
1103 while (--i >= 0)
1105 XVECEXP (split, 0, i) = copy_rtx (XVECEXP (desc, 1, i));
1106 remove_constraints (XVECEXP (split, 0, i));
1109 /* If the split condition starts with "&&", append it to the
1110 insn condition to create the new split condition. */
1111 split_cond = XSTR (desc, 4);
1112 if (split_cond[0] == '&' && split_cond[1] == '&')
1114 rtx_reader_ptr->copy_md_ptr_loc (split_cond + 2, split_cond);
1115 split_cond = rtx_reader_ptr->join_c_conditions (XSTR (desc, 2),
1116 split_cond + 2);
1118 else if (GET_CODE (desc) == DEFINE_INSN_AND_REWRITE)
1119 error_at (loc, "the rewrite condition must start with `&&'");
1120 XSTR (split, 1) = split_cond;
1121 if (GET_CODE (desc) == DEFINE_INSN_AND_REWRITE)
1122 XVEC (split, 2) = gen_rewrite_sequence (XVEC (desc, 1));
1123 else
1124 XVEC (split, 2) = XVEC (desc, 5);
1125 XSTR (split, 3) = XSTR (desc, split_code);
1127 /* Fix up the DEFINE_INSN. */
1128 attr = XVEC (desc, split_code + 1);
1129 PUT_CODE (desc, DEFINE_INSN);
1130 XVEC (desc, 4) = attr;
1131 convert_syntax (desc, loc);
1133 /* Queue them. */
1134 insn_elem = queue_pattern (desc, &define_insn_tail, loc);
1135 split_elem = queue_pattern (split, &other_tail, loc);
1136 insn_elem->split = split_elem;
1137 break;
1140 default:
1141 queue_pattern (desc, &other_tail, loc);
1142 break;
1146 /* Return true if attribute PREDICABLE is true for ELEM, which holds
1147 a DEFINE_INSN. */
1149 static int
1150 is_predicable (class queue_elem *elem)
1152 rtvec vec = XVEC (elem->data, 4);
1153 const char *value;
1154 int i;
1156 if (! vec)
1157 return predicable_default;
1159 for (i = GET_NUM_ELEM (vec) - 1; i >= 0; --i)
1161 rtx sub = RTVEC_ELT (vec, i);
1162 switch (GET_CODE (sub))
1164 case SET_ATTR:
1165 if (strcmp (XSTR (sub, 0), "predicable") == 0)
1167 value = XSTR (sub, 1);
1168 goto found;
1170 break;
1172 case SET_ATTR_ALTERNATIVE:
1173 if (strcmp (XSTR (sub, 0), "predicable") == 0)
1175 error_at (elem->loc, "multiple alternatives for `predicable'");
1176 return 0;
1178 break;
1180 case SET:
1181 if (GET_CODE (SET_DEST (sub)) != ATTR
1182 || strcmp (XSTR (SET_DEST (sub), 0), "predicable") != 0)
1183 break;
1184 sub = SET_SRC (sub);
1185 if (GET_CODE (sub) == CONST_STRING)
1187 value = XSTR (sub, 0);
1188 goto found;
1191 /* ??? It would be possible to handle this if we really tried.
1192 It's not easy though, and I'm not going to bother until it
1193 really proves necessary. */
1194 error_at (elem->loc, "non-constant value for `predicable'");
1195 return 0;
1197 default:
1198 gcc_unreachable ();
1202 return predicable_default;
1204 found:
1205 /* Find out which value we're looking at. Multiple alternatives means at
1206 least one is predicable. */
1207 if (strchr (value, ',') != NULL)
1208 return 1;
1209 if (strcmp (value, predicable_true) == 0)
1210 return 1;
1211 if (strcmp (value, predicable_false) == 0)
1212 return 0;
1214 error_at (elem->loc, "unknown value `%s' for `predicable' attribute", value);
1215 return 0;
1218 /* Find attribute SUBST in ELEM and assign NEW_VALUE to it. */
1219 static void
1220 change_subst_attribute (class queue_elem *elem,
1221 class queue_elem *subst_elem,
1222 const char *new_value)
1224 rtvec attrs_vec = XVEC (elem->data, 4);
1225 const char *subst_name = XSTR (subst_elem->data, 0);
1226 int i;
1228 if (! attrs_vec)
1229 return;
1231 for (i = GET_NUM_ELEM (attrs_vec) - 1; i >= 0; --i)
1233 rtx cur_attr = RTVEC_ELT (attrs_vec, i);
1234 if (GET_CODE (cur_attr) != SET_ATTR)
1235 continue;
1236 if (strcmp (XSTR (cur_attr, 0), subst_name) == 0)
1238 XSTR (cur_attr, 1) = new_value;
1239 return;
1244 /* Return true if ELEM has the attribute with the name of DEFINE_SUBST
1245 represented by SUBST_ELEM and this attribute has value SUBST_TRUE.
1246 DEFINE_SUBST isn't applied to patterns without such attribute. In other
1247 words, we suppose the default value of the attribute to be 'no' since it is
1248 always generated automatically in read-rtl.cc. */
1249 static bool
1250 has_subst_attribute (class queue_elem *elem, class queue_elem *subst_elem)
1252 rtvec attrs_vec = XVEC (elem->data, 4);
1253 const char *value, *subst_name = XSTR (subst_elem->data, 0);
1254 int i;
1256 if (! attrs_vec)
1257 return false;
1259 for (i = GET_NUM_ELEM (attrs_vec) - 1; i >= 0; --i)
1261 rtx cur_attr = RTVEC_ELT (attrs_vec, i);
1262 switch (GET_CODE (cur_attr))
1264 case SET_ATTR:
1265 if (strcmp (XSTR (cur_attr, 0), subst_name) == 0)
1267 value = XSTR (cur_attr, 1);
1268 goto found;
1270 break;
1272 case SET:
1273 if (GET_CODE (SET_DEST (cur_attr)) != ATTR
1274 || strcmp (XSTR (SET_DEST (cur_attr), 0), subst_name) != 0)
1275 break;
1276 cur_attr = SET_SRC (cur_attr);
1277 if (GET_CODE (cur_attr) == CONST_STRING)
1279 value = XSTR (cur_attr, 0);
1280 goto found;
1283 /* Only (set_attr "subst" "yes/no") and
1284 (set (attr "subst" (const_string "yes/no")))
1285 are currently allowed. */
1286 error_at (elem->loc, "unsupported value for `%s'", subst_name);
1287 return false;
1289 case SET_ATTR_ALTERNATIVE:
1290 if (strcmp (XSTR (cur_attr, 0), subst_name) == 0)
1291 error_at (elem->loc,
1292 "%s: `set_attr_alternative' is unsupported by "
1293 "`define_subst'", XSTR (elem->data, 0));
1294 return false;
1297 default:
1298 gcc_unreachable ();
1302 return false;
1304 found:
1305 if (strcmp (value, subst_true) == 0)
1306 return true;
1307 if (strcmp (value, subst_false) == 0)
1308 return false;
1310 error_at (elem->loc, "unknown value `%s' for `%s' attribute",
1311 value, subst_name);
1312 return false;
1315 /* Compare RTL-template of original define_insn X to input RTL-template of
1316 define_subst PT. Return 1 if the templates match, 0 otherwise.
1317 During the comparison, the routine also fills global_array OPERAND_DATA. */
1318 static bool
1319 subst_pattern_match (rtx x, rtx pt, file_location loc)
1321 RTX_CODE code, code_pt;
1322 int i, j, len;
1323 const char *fmt, *pred_name;
1325 code = GET_CODE (x);
1326 code_pt = GET_CODE (pt);
1328 if (code_pt == MATCH_OPERAND)
1330 /* MATCH_DUP, and MATCH_OP_DUP don't have a specified mode, so we
1331 always accept them. */
1332 if (GET_MODE (pt) != VOIDmode && GET_MODE (x) != GET_MODE (pt)
1333 && (code != MATCH_DUP && code != MATCH_OP_DUP))
1334 return false; /* Modes don't match. */
1336 if (code == MATCH_OPERAND)
1338 pred_name = XSTR (pt, 1);
1339 if (pred_name[0] != 0)
1341 const struct pred_data *pred_pt = lookup_predicate (pred_name);
1342 if (!pred_pt || pred_pt != lookup_predicate (XSTR (x, 1)))
1343 return false; /* Predicates don't match. */
1347 gcc_assert (XINT (pt, 0) >= 0 && XINT (pt, 0) < MAX_OPERANDS);
1348 operand_data[XINT (pt, 0)] = x;
1349 return true;
1352 if (code_pt == MATCH_OPERATOR)
1354 int x_vecexp_pos = -1;
1356 /* Compare modes. */
1357 if (GET_MODE (pt) != VOIDmode && GET_MODE (x) != GET_MODE (pt))
1358 return false;
1360 /* In case X is also match_operator, compare predicates. */
1361 if (code == MATCH_OPERATOR)
1363 pred_name = XSTR (pt, 1);
1364 if (pred_name[0] != 0)
1366 const struct pred_data *pred_pt = lookup_predicate (pred_name);
1367 if (!pred_pt || pred_pt != lookup_predicate (XSTR (x, 1)))
1368 return false;
1372 /* Compare operands.
1373 MATCH_OPERATOR in input template could match in original template
1374 either 1) MATCH_OPERAND, 2) UNSPEC, 3) ordinary operation (like PLUS).
1375 In the first case operands are at (XVECEXP (x, 2, j)), in the second
1376 - at (XVECEXP (x, 0, j)), in the last one - (XEXP (x, j)).
1377 X_VECEXP_POS variable shows, where to look for these operands. */
1378 if (code == UNSPEC
1379 || code == UNSPEC_VOLATILE)
1380 x_vecexp_pos = 0;
1381 else if (code == MATCH_OPERATOR)
1382 x_vecexp_pos = 2;
1383 else
1384 x_vecexp_pos = -1;
1386 /* MATCH_OPERATOR or UNSPEC case. */
1387 if (x_vecexp_pos >= 0)
1389 /* Compare operands number in X and PT. */
1390 if (XVECLEN (x, x_vecexp_pos) != XVECLEN (pt, 2))
1391 return false;
1392 for (j = 0; j < XVECLEN (pt, 2); j++)
1393 if (!subst_pattern_match (XVECEXP (x, x_vecexp_pos, j),
1394 XVECEXP (pt, 2, j), loc))
1395 return false;
1398 /* Ordinary operator. */
1399 else
1401 /* Compare operands number in X and PT.
1402 We count operands differently for X and PT since we compare
1403 an operator (with operands directly in RTX) and MATCH_OPERATOR
1404 (that has a vector with operands). */
1405 if (GET_RTX_LENGTH (code) != XVECLEN (pt, 2))
1406 return false;
1407 for (j = 0; j < XVECLEN (pt, 2); j++)
1408 if (!subst_pattern_match (XEXP (x, j), XVECEXP (pt, 2, j), loc))
1409 return false;
1412 /* Store the operand to OPERAND_DATA array. */
1413 gcc_assert (XINT (pt, 0) >= 0 && XINT (pt, 0) < MAX_OPERANDS);
1414 operand_data[XINT (pt, 0)] = x;
1415 return true;
1418 if (code_pt == MATCH_PAR_DUP
1419 || code_pt == MATCH_DUP
1420 || code_pt == MATCH_OP_DUP
1421 || code_pt == MATCH_SCRATCH
1422 || code_pt == MATCH_PARALLEL)
1424 /* Currently interface for these constructions isn't defined -
1425 probably they aren't needed in input template of define_subst at all.
1426 So, for now their usage in define_subst is forbidden. */
1427 error_at (loc, "%s cannot be used in define_subst",
1428 GET_RTX_NAME (code_pt));
1431 gcc_assert (code != MATCH_PAR_DUP
1432 && code_pt != MATCH_DUP
1433 && code_pt != MATCH_OP_DUP
1434 && code_pt != MATCH_SCRATCH
1435 && code_pt != MATCH_PARALLEL
1436 && code_pt != MATCH_OPERAND
1437 && code_pt != MATCH_OPERATOR);
1438 /* If PT is none of the handled above, then we match only expressions with
1439 the same code in X. */
1440 if (code != code_pt)
1441 return false;
1443 fmt = GET_RTX_FORMAT (code_pt);
1444 len = GET_RTX_LENGTH (code_pt);
1446 for (i = 0; i < len; i++)
1448 if (fmt[i] == '0')
1449 break;
1451 switch (fmt[i])
1453 case 'r': case 'p': case 'i': case 'w': case 's':
1454 continue;
1456 case 'e': case 'u':
1457 if (!subst_pattern_match (XEXP (x, i), XEXP (pt, i), loc))
1458 return false;
1459 break;
1460 case 'E':
1462 if (XVECLEN (x, i) != XVECLEN (pt, i))
1463 return false;
1464 for (j = 0; j < XVECLEN (pt, i); j++)
1465 if (!subst_pattern_match (XVECEXP (x, i, j),
1466 XVECEXP (pt, i, j), loc))
1467 return false;
1468 break;
1470 default:
1471 gcc_unreachable ();
1475 return true;
1478 /* Examine the attribute "predicable"; discover its boolean values
1479 and its default. */
1481 static void
1482 identify_predicable_attribute (void)
1484 class queue_elem *elem;
1485 char *p_true, *p_false;
1486 const char *value;
1488 /* Look for the DEFINE_ATTR for `predicable', which must exist. */
1489 for (elem = define_attr_queue; elem ; elem = elem->next)
1490 if (strcmp (XSTR (elem->data, 0), "predicable") == 0)
1491 goto found;
1493 error_at (define_cond_exec_queue->loc,
1494 "attribute `predicable' not defined");
1495 return;
1497 found:
1498 value = XSTR (elem->data, 1);
1499 p_false = xstrdup (value);
1500 p_true = strchr (p_false, ',');
1501 if (p_true == NULL || strchr (++p_true, ',') != NULL)
1503 error_at (elem->loc, "attribute `predicable' is not a boolean");
1504 free (p_false);
1505 return;
1507 p_true[-1] = '\0';
1509 predicable_true = p_true;
1510 predicable_false = p_false;
1512 switch (GET_CODE (XEXP (elem->data, 2)))
1514 case CONST_STRING:
1515 value = XSTR (XEXP (elem->data, 2), 0);
1516 break;
1518 case CONST:
1519 error_at (elem->loc, "attribute `predicable' cannot be const");
1520 free (p_false);
1521 return;
1523 default:
1524 error_at (elem->loc,
1525 "attribute `predicable' must have a constant default");
1526 free (p_false);
1527 return;
1530 if (strcmp (value, p_true) == 0)
1531 predicable_default = 1;
1532 else if (strcmp (value, p_false) == 0)
1533 predicable_default = 0;
1534 else
1536 error_at (elem->loc, "unknown value `%s' for `predicable' attribute",
1537 value);
1538 free (p_false);
1542 /* Return the number of alternatives in constraint S. */
1544 static int
1545 n_alternatives (const char *s)
1547 int n = 1;
1549 if (s)
1550 while (*s)
1551 n += (*s++ == ',');
1553 return n;
1556 /* The routine scans rtl PATTERN, find match_operand in it and counts
1557 number of alternatives. If PATTERN contains several match_operands
1558 with different number of alternatives, error is emitted, and the
1559 routine returns 0. If all match_operands in PATTERN have the same
1560 number of alternatives, it's stored in N_ALT, and the routine returns 1.
1561 LOC is the location of PATTERN, for error reporting. */
1562 static int
1563 get_alternatives_number (rtx pattern, int *n_alt, file_location loc)
1565 const char *fmt;
1566 enum rtx_code code;
1567 int i, j, len;
1569 if (!n_alt)
1570 return 0;
1572 code = GET_CODE (pattern);
1573 switch (code)
1575 case MATCH_OPERAND:
1576 i = n_alternatives (XSTR (pattern, 2));
1577 /* n_alternatives returns 1 if constraint string is empty -
1578 here we fix it up. */
1579 if (!*(XSTR (pattern, 2)))
1580 i = 0;
1581 if (*n_alt <= 0)
1582 *n_alt = i;
1584 else if (i && i != *n_alt)
1586 error_at (loc, "wrong number of alternatives in operand %d",
1587 XINT (pattern, 0));
1588 return 0;
1591 default:
1592 break;
1595 fmt = GET_RTX_FORMAT (code);
1596 len = GET_RTX_LENGTH (code);
1597 for (i = 0; i < len; i++)
1599 switch (fmt[i])
1601 case 'e': case 'u':
1602 if (!get_alternatives_number (XEXP (pattern, i), n_alt, loc))
1603 return 0;
1604 break;
1606 case 'V':
1607 if (XVEC (pattern, i) == NULL)
1608 break;
1609 /* FALLTHRU */
1611 case 'E':
1612 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
1613 if (!get_alternatives_number (XVECEXP (pattern, i, j), n_alt, loc))
1614 return 0;
1615 break;
1617 case 'r': case 'p': case 'i': case 'w':
1618 case '0': case 's': case 'S': case 'T':
1619 break;
1621 default:
1622 gcc_unreachable ();
1625 return 1;
1628 /* Determine how many alternatives there are in INSN, and how many
1629 operands. */
1631 static void
1632 collect_insn_data (rtx pattern, int *palt, int *pmax)
1634 const char *fmt;
1635 enum rtx_code code;
1636 int i, j, len;
1638 code = GET_CODE (pattern);
1639 switch (code)
1641 case MATCH_OPERAND:
1642 case MATCH_SCRATCH:
1643 i = n_alternatives (XSTR (pattern, code == MATCH_SCRATCH ? 1 : 2));
1644 *palt = (i > *palt ? i : *palt);
1645 /* Fall through. */
1647 case MATCH_OPERATOR:
1648 case MATCH_PARALLEL:
1649 i = XINT (pattern, 0);
1650 if (i > *pmax)
1651 *pmax = i;
1652 break;
1654 default:
1655 break;
1658 fmt = GET_RTX_FORMAT (code);
1659 len = GET_RTX_LENGTH (code);
1660 for (i = 0; i < len; i++)
1662 switch (fmt[i])
1664 case 'e': case 'u':
1665 collect_insn_data (XEXP (pattern, i), palt, pmax);
1666 break;
1668 case 'V':
1669 if (XVEC (pattern, i) == NULL)
1670 break;
1671 /* Fall through. */
1672 case 'E':
1673 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
1674 collect_insn_data (XVECEXP (pattern, i, j), palt, pmax);
1675 break;
1677 case 'r': case 'p': case 'i': case 'w':
1678 case '0': case 's': case 'S': case 'T':
1679 break;
1681 default:
1682 gcc_unreachable ();
1687 static rtx
1688 alter_predicate_for_insn (rtx pattern, int alt, int max_op,
1689 file_location loc)
1691 const char *fmt;
1692 enum rtx_code code;
1693 int i, j, len;
1695 code = GET_CODE (pattern);
1696 switch (code)
1698 case MATCH_OPERAND:
1700 const char *c = XSTR (pattern, 2);
1702 if (n_alternatives (c) != 1)
1704 error_at (loc, "too many alternatives for operand %d",
1705 XINT (pattern, 0));
1706 return NULL;
1709 /* Replicate C as needed to fill out ALT alternatives. */
1710 if (c && *c && alt > 1)
1712 size_t c_len = strlen (c);
1713 size_t len = alt * (c_len + 1);
1714 char *new_c = XNEWVEC (char, len);
1716 memcpy (new_c, c, c_len);
1717 for (i = 1; i < alt; ++i)
1719 new_c[i * (c_len + 1) - 1] = ',';
1720 memcpy (&new_c[i * (c_len + 1)], c, c_len);
1722 new_c[len - 1] = '\0';
1723 XSTR (pattern, 2) = new_c;
1726 /* Fall through. */
1728 case MATCH_OPERATOR:
1729 case MATCH_SCRATCH:
1730 case MATCH_PARALLEL:
1731 case MATCH_DUP:
1732 XINT (pattern, 0) += max_op;
1733 break;
1735 default:
1736 break;
1739 fmt = GET_RTX_FORMAT (code);
1740 len = GET_RTX_LENGTH (code);
1741 for (i = 0; i < len; i++)
1743 rtx r;
1745 switch (fmt[i])
1747 case 'e': case 'u':
1748 r = alter_predicate_for_insn (XEXP (pattern, i), alt, max_op, loc);
1749 if (r == NULL)
1750 return r;
1751 break;
1753 case 'E':
1754 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
1756 r = alter_predicate_for_insn (XVECEXP (pattern, i, j),
1757 alt, max_op, loc);
1758 if (r == NULL)
1759 return r;
1761 break;
1763 case 'r': case 'p': case 'i': case 'w': case '0': case 's':
1764 break;
1766 default:
1767 gcc_unreachable ();
1771 return pattern;
1774 /* Duplicate constraints in PATTERN. If pattern is from original
1775 rtl-template, we need to duplicate each alternative - for that we
1776 need to use duplicate_each_alternative () as a functor ALTER.
1777 If pattern is from output-pattern of define_subst, we need to
1778 duplicate constraints in another way - with duplicate_alternatives ().
1779 N_DUP is multiplication factor. */
1780 static rtx
1781 alter_constraints (rtx pattern, int n_dup, constraints_handler_t alter)
1783 const char *fmt;
1784 enum rtx_code code;
1785 int i, j, len;
1787 code = GET_CODE (pattern);
1788 switch (code)
1790 case MATCH_OPERAND:
1791 XSTR (pattern, 2) = alter (XSTR (pattern, 2), n_dup);
1792 break;
1793 case MATCH_SCRATCH:
1794 XSTR (pattern, 1) = alter (XSTR (pattern, 1), n_dup);
1795 break;
1797 default:
1798 break;
1801 fmt = GET_RTX_FORMAT (code);
1802 len = GET_RTX_LENGTH (code);
1803 for (i = 0; i < len; i++)
1805 rtx r;
1807 switch (fmt[i])
1809 case 'e': case 'u':
1810 r = alter_constraints (XEXP (pattern, i), n_dup, alter);
1811 if (r == NULL)
1812 return r;
1813 break;
1815 case 'E':
1816 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
1818 r = alter_constraints (XVECEXP (pattern, i, j), n_dup, alter);
1819 if (r == NULL)
1820 return r;
1822 break;
1824 case 'r': case 'p': case 'i': case 'w': case '0': case 's':
1825 break;
1827 default:
1828 break;
1832 return pattern;
1835 static const char *
1836 alter_test_for_insn (class queue_elem *ce_elem,
1837 class queue_elem *insn_elem)
1839 return rtx_reader_ptr->join_c_conditions (XSTR (ce_elem->data, 1),
1840 XSTR (insn_elem->data, 2));
1843 /* Modify VAL, which is an attribute expression for the "enabled" attribute,
1844 to take "ce_enabled" into account. Return the new expression. */
1845 static rtx
1846 modify_attr_enabled_ce (rtx val)
1848 rtx eq_attr, str;
1849 rtx ite;
1850 eq_attr = rtx_alloc (EQ_ATTR);
1851 ite = rtx_alloc (IF_THEN_ELSE);
1852 str = rtx_alloc (CONST_STRING);
1854 XSTR (eq_attr, 0) = "ce_enabled";
1855 XSTR (eq_attr, 1) = "yes";
1856 XSTR (str, 0) = "no";
1857 XEXP (ite, 0) = eq_attr;
1858 XEXP (ite, 1) = val;
1859 XEXP (ite, 2) = str;
1861 return ite;
1864 /* Alter the attribute vector of INSN, which is a COND_EXEC variant created
1865 from a define_insn pattern. We must modify the "predicable" attribute
1866 to be named "ce_enabled", and also change any "enabled" attribute that's
1867 present so that it takes ce_enabled into account.
1868 We rely on the fact that INSN was created with copy_rtx, and modify data
1869 in-place. */
1871 static void
1872 alter_attrs_for_insn (rtx insn)
1874 static bool global_changes_made = false;
1875 rtvec vec = XVEC (insn, 4);
1876 rtvec new_vec;
1877 rtx val, set;
1878 int num_elem;
1879 int predicable_idx = -1;
1880 int enabled_idx = -1;
1881 int i;
1883 if (! vec)
1884 return;
1886 num_elem = GET_NUM_ELEM (vec);
1887 for (i = num_elem - 1; i >= 0; --i)
1889 rtx sub = RTVEC_ELT (vec, i);
1890 switch (GET_CODE (sub))
1892 case SET_ATTR:
1893 if (strcmp (XSTR (sub, 0), "predicable") == 0)
1895 predicable_idx = i;
1896 XSTR (sub, 0) = "ce_enabled";
1898 else if (strcmp (XSTR (sub, 0), "enabled") == 0)
1900 enabled_idx = i;
1901 XSTR (sub, 0) = "nonce_enabled";
1903 break;
1905 case SET_ATTR_ALTERNATIVE:
1906 if (strcmp (XSTR (sub, 0), "predicable") == 0)
1907 /* We already give an error elsewhere. */
1908 return;
1909 else if (strcmp (XSTR (sub, 0), "enabled") == 0)
1911 enabled_idx = i;
1912 XSTR (sub, 0) = "nonce_enabled";
1914 break;
1916 case SET:
1917 if (GET_CODE (SET_DEST (sub)) != ATTR)
1918 break;
1919 if (strcmp (XSTR (SET_DEST (sub), 0), "predicable") == 0)
1921 sub = SET_SRC (sub);
1922 if (GET_CODE (sub) == CONST_STRING)
1924 predicable_idx = i;
1925 XSTR (sub, 0) = "ce_enabled";
1927 else
1928 /* We already give an error elsewhere. */
1929 return;
1930 break;
1932 if (strcmp (XSTR (SET_DEST (sub), 0), "enabled") == 0)
1934 enabled_idx = i;
1935 XSTR (SET_DEST (sub), 0) = "nonce_enabled";
1937 break;
1939 default:
1940 gcc_unreachable ();
1943 if (predicable_idx == -1)
1944 return;
1946 if (!global_changes_made)
1948 class queue_elem *elem;
1950 global_changes_made = true;
1951 add_define_attr ("ce_enabled");
1952 add_define_attr ("nonce_enabled");
1954 for (elem = define_attr_queue; elem ; elem = elem->next)
1955 if (strcmp (XSTR (elem->data, 0), "enabled") == 0)
1957 XEXP (elem->data, 2)
1958 = modify_attr_enabled_ce (XEXP (elem->data, 2));
1961 if (enabled_idx == -1)
1962 return;
1964 new_vec = rtvec_alloc (num_elem + 1);
1965 for (i = 0; i < num_elem; i++)
1966 RTVEC_ELT (new_vec, i) = RTVEC_ELT (vec, i);
1967 val = rtx_alloc (IF_THEN_ELSE);
1968 XEXP (val, 0) = rtx_alloc (EQ_ATTR);
1969 XEXP (val, 1) = rtx_alloc (CONST_STRING);
1970 XEXP (val, 2) = rtx_alloc (CONST_STRING);
1971 XSTR (XEXP (val, 0), 0) = "nonce_enabled";
1972 XSTR (XEXP (val, 0), 1) = "yes";
1973 XSTR (XEXP (val, 1), 0) = "yes";
1974 XSTR (XEXP (val, 2), 0) = "no";
1975 set = rtx_alloc (SET);
1976 SET_DEST (set) = rtx_alloc (ATTR);
1977 XSTR (SET_DEST (set), 0) = "enabled";
1978 SET_SRC (set) = modify_attr_enabled_ce (val);
1979 RTVEC_ELT (new_vec, i) = set;
1980 XVEC (insn, 4) = new_vec;
1983 /* As number of constraints is changed after define_subst, we need to
1984 process attributes as well - we need to duplicate them the same way
1985 that we duplicated constraints in original pattern
1986 ELEM is a queue element, containing our rtl-template,
1987 N_DUP - multiplication factor. */
1988 static void
1989 alter_attrs_for_subst_insn (class queue_elem * elem, int n_dup)
1991 rtvec vec = XVEC (elem->data, 4);
1992 int num_elem;
1993 int i;
1995 if (n_dup < 2 || ! vec)
1996 return;
1998 num_elem = GET_NUM_ELEM (vec);
1999 for (i = num_elem - 1; i >= 0; --i)
2001 rtx sub = RTVEC_ELT (vec, i);
2002 switch (GET_CODE (sub))
2004 case SET_ATTR:
2005 if (strchr (XSTR (sub, 1), ',') != NULL)
2006 XSTR (sub, 1) = duplicate_alternatives (XSTR (sub, 1), n_dup);
2007 break;
2009 case SET_ATTR_ALTERNATIVE:
2010 case SET:
2011 error_at (elem->loc,
2012 "%s: `define_subst' does not support attributes "
2013 "assigned by `set' and `set_attr_alternative'",
2014 XSTR (elem->data, 0));
2015 return;
2017 default:
2018 gcc_unreachable ();
2023 /* Adjust all of the operand numbers in SRC to match the shift they'll
2024 get from an operand displacement of DISP. Return a pointer after the
2025 adjusted string. */
2027 static char *
2028 shift_output_template (char *dest, const char *src, int disp)
2030 while (*src)
2032 char c = *src++;
2033 *dest++ = c;
2034 if (c == '%')
2036 c = *src++;
2037 if (ISDIGIT ((unsigned char) c))
2038 c += disp;
2039 else if (ISALPHA (c))
2041 *dest++ = c;
2042 c = *src++ + disp;
2044 *dest++ = c;
2048 return dest;
2051 static const char *
2052 alter_output_for_insn (class queue_elem *ce_elem,
2053 class queue_elem *insn_elem,
2054 int alt, int max_op)
2056 const char *ce_out, *insn_out;
2057 char *result, *p;
2058 size_t len, ce_len, insn_len;
2060 /* ??? Could coordinate with genoutput to not duplicate code here. */
2062 ce_out = XSTR (ce_elem->data, 2);
2063 insn_out = XTMPL (insn_elem->data, 3);
2064 if (!ce_out || *ce_out == '\0')
2065 return insn_out;
2067 ce_len = strlen (ce_out);
2068 insn_len = strlen (insn_out);
2070 if (*insn_out == '*')
2071 /* You must take care of the predicate yourself. */
2072 return insn_out;
2074 if (*insn_out == '@')
2076 len = (ce_len + 1) * alt + insn_len + 1;
2077 p = result = XNEWVEC (char, len);
2082 *p++ = *insn_out++;
2083 while (ISSPACE ((unsigned char) *insn_out));
2085 if (*insn_out != '#')
2087 p = shift_output_template (p, ce_out, max_op);
2088 *p++ = ' ';
2092 *p++ = *insn_out++;
2093 while (*insn_out && *insn_out != '\n');
2095 while (*insn_out);
2096 *p = '\0';
2098 else
2100 len = ce_len + 1 + insn_len + 1;
2101 result = XNEWVEC (char, len);
2103 p = shift_output_template (result, ce_out, max_op);
2104 *p++ = ' ';
2105 memcpy (p, insn_out, insn_len + 1);
2108 return result;
2111 /* From string STR "a,b,c" produce "a,b,c,a,b,c,a,b,c", i.e. original
2112 string, duplicated N_DUP times. */
2114 static const char *
2115 duplicate_alternatives (const char * str, int n_dup)
2117 int i, len, new_len;
2118 char *result, *sp;
2119 const char *cp;
2121 if (n_dup < 2)
2122 return str;
2124 while (ISSPACE (*str))
2125 str++;
2127 if (*str == '\0')
2128 return str;
2130 cp = str;
2131 len = strlen (str);
2132 new_len = (len + 1) * n_dup;
2134 sp = result = XNEWVEC (char, new_len);
2136 /* Global modifier characters mustn't be duplicated: skip if found. */
2137 if (*cp == '=' || *cp == '+' || *cp == '%')
2139 *sp++ = *cp++;
2140 len--;
2143 /* Copy original constraints N_DUP times. */
2144 for (i = 0; i < n_dup; i++, sp += len+1)
2146 memcpy (sp, cp, len);
2147 *(sp+len) = (i == n_dup - 1) ? '\0' : ',';
2150 return result;
2153 /* From string STR "a,b,c" produce "a,a,a,b,b,b,c,c,c", i.e. string where
2154 each alternative from the original string is duplicated N_DUP times. */
2155 static const char *
2156 duplicate_each_alternative (const char * str, int n_dup)
2158 int i, len, new_len;
2159 char *result, *sp, *ep, *cp;
2161 if (n_dup < 2)
2162 return str;
2164 while (ISSPACE (*str))
2165 str++;
2167 if (*str == '\0')
2168 return str;
2170 cp = xstrdup (str);
2172 new_len = (strlen (cp) + 1) * n_dup;
2174 sp = result = XNEWVEC (char, new_len);
2176 /* Global modifier characters mustn't be duplicated: skip if found. */
2177 if (*cp == '=' || *cp == '+' || *cp == '%')
2178 *sp++ = *cp++;
2182 if ((ep = strchr (cp, ',')) != NULL)
2183 *ep++ = '\0';
2184 len = strlen (cp);
2186 /* Copy a constraint N_DUP times. */
2187 for (i = 0; i < n_dup; i++, sp += len + 1)
2189 memcpy (sp, cp, len);
2190 *(sp+len) = (ep == NULL && i == n_dup - 1) ? '\0' : ',';
2193 cp = ep;
2195 while (cp != NULL);
2197 return result;
2200 /* Alter the output of INSN whose pattern was modified by
2201 DEFINE_SUBST. We must replicate output strings according
2202 to the new number of alternatives ALT in substituted pattern.
2203 If ALT equals 1, output has one alternative or defined by C
2204 code, then output is returned without any changes. */
2206 static const char *
2207 alter_output_for_subst_insn (rtx insn, int alt)
2209 const char *insn_out, *old_out;
2210 char *new_out, *cp;
2211 size_t old_len, new_len;
2212 int j;
2214 insn_out = XTMPL (insn, 3);
2216 if (alt < 2 || *insn_out != '@')
2217 return insn_out;
2219 old_out = insn_out + 1;
2220 while (ISSPACE (*old_out))
2221 old_out++;
2222 old_len = strlen (old_out);
2224 new_len = alt * (old_len + 1) + 1;
2226 new_out = XNEWVEC (char, new_len);
2227 new_out[0] = '@';
2229 for (j = 0, cp = new_out + 1; j < alt; j++, cp += old_len + 1)
2231 memcpy (cp, old_out, old_len);
2232 cp[old_len] = (j == alt - 1) ? '\0' : '\n';
2235 return new_out;
2238 /* Replicate insns as appropriate for the given DEFINE_COND_EXEC. */
2240 static void
2241 process_one_cond_exec (class queue_elem *ce_elem)
2243 class queue_elem *insn_elem;
2244 for (insn_elem = define_insn_queue; insn_elem ; insn_elem = insn_elem->next)
2246 int alternatives, max_operand;
2247 rtx pred, insn, pattern, split;
2248 char *new_name;
2249 int i;
2251 if (! is_predicable (insn_elem))
2252 continue;
2254 alternatives = 1;
2255 max_operand = -1;
2256 collect_insn_data (insn_elem->data, &alternatives, &max_operand);
2257 max_operand += 1;
2259 if (XVECLEN (ce_elem->data, 0) != 1)
2261 error_at (ce_elem->loc, "too many patterns in predicate");
2262 return;
2265 pred = copy_rtx (XVECEXP (ce_elem->data, 0, 0));
2266 pred = alter_predicate_for_insn (pred, alternatives, max_operand,
2267 ce_elem->loc);
2268 if (pred == NULL)
2269 return;
2271 /* Construct a new pattern for the new insn. */
2272 insn = copy_rtx (insn_elem->data);
2273 new_name = XNEWVAR (char, strlen XSTR (insn_elem->data, 0) + 4);
2274 sprintf (new_name, "*p %s", XSTR (insn_elem->data, 0));
2275 XSTR (insn, 0) = new_name;
2276 pattern = rtx_alloc (COND_EXEC);
2277 XEXP (pattern, 0) = pred;
2278 XEXP (pattern, 1) = add_implicit_parallel (XVEC (insn, 1));
2279 XVEC (insn, 1) = rtvec_alloc (1);
2280 XVECEXP (insn, 1, 0) = pattern;
2282 if (XVEC (ce_elem->data, 3) != NULL)
2284 rtvec attributes = rtvec_alloc (XVECLEN (insn, 4)
2285 + XVECLEN (ce_elem->data, 3));
2286 int i = 0;
2287 int j = 0;
2288 for (i = 0; i < XVECLEN (insn, 4); i++)
2289 RTVEC_ELT (attributes, i) = XVECEXP (insn, 4, i);
2291 for (j = 0; j < XVECLEN (ce_elem->data, 3); j++, i++)
2292 RTVEC_ELT (attributes, i) = XVECEXP (ce_elem->data, 3, j);
2294 XVEC (insn, 4) = attributes;
2297 XSTR (insn, 2) = alter_test_for_insn (ce_elem, insn_elem);
2298 XTMPL (insn, 3) = alter_output_for_insn (ce_elem, insn_elem,
2299 alternatives, max_operand);
2300 alter_attrs_for_insn (insn);
2302 /* Put the new pattern on the `other' list so that it
2303 (a) is not reprocessed by other define_cond_exec patterns
2304 (b) appears after all normal define_insn patterns.
2306 ??? B is debatable. If one has normal insns that match
2307 cond_exec patterns, they will be preferred over these
2308 generated patterns. Whether this matters in practice, or if
2309 it's a good thing, or whether we should thread these new
2310 patterns into the define_insn chain just after their generator
2311 is something we'll have to experiment with. */
2313 queue_pattern (insn, &other_tail, insn_elem->loc);
2315 if (!insn_elem->split)
2316 continue;
2318 /* If the original insn came from a define_insn_and_split,
2319 generate a new split to handle the predicated insn. */
2320 split = copy_rtx (insn_elem->split->data);
2321 /* Predicate the pattern matched by the split. */
2322 pattern = rtx_alloc (COND_EXEC);
2323 XEXP (pattern, 0) = pred;
2324 XEXP (pattern, 1) = add_implicit_parallel (XVEC (split, 0));
2325 XVEC (split, 0) = rtvec_alloc (1);
2326 XVECEXP (split, 0, 0) = pattern;
2328 /* Predicate all of the insns generated by the split. */
2329 for (i = 0; i < XVECLEN (split, 2); i++)
2331 pattern = rtx_alloc (COND_EXEC);
2332 XEXP (pattern, 0) = pred;
2333 XEXP (pattern, 1) = XVECEXP (split, 2, i);
2334 XVECEXP (split, 2, i) = pattern;
2336 /* Add the new split to the queue. */
2337 queue_pattern (split, &other_tail, insn_elem->split->loc);
2341 /* Try to apply define_substs to the given ELEM.
2342 Only define_substs, specified via attributes would be applied.
2343 If attribute, requiring define_subst, is set, but no define_subst
2344 was applied, ELEM would be deleted. */
2346 static void
2347 process_substs_on_one_elem (class queue_elem *elem,
2348 class queue_elem *queue)
2350 class queue_elem *subst_elem;
2351 int i, j, patterns_match;
2353 for (subst_elem = define_subst_queue;
2354 subst_elem; subst_elem = subst_elem->next)
2356 int alternatives, alternatives_subst;
2357 rtx subst_pattern;
2358 rtvec subst_pattern_vec;
2360 if (!has_subst_attribute (elem, subst_elem))
2361 continue;
2363 /* Compare original rtl-pattern from define_insn with input
2364 pattern from define_subst.
2365 Also, check if numbers of alternatives are the same in all
2366 match_operands. */
2367 if (XVECLEN (elem->data, 1) != XVECLEN (subst_elem->data, 1))
2368 continue;
2369 patterns_match = 1;
2370 alternatives = -1;
2371 alternatives_subst = -1;
2372 for (j = 0; j < XVECLEN (elem->data, 1); j++)
2374 if (!subst_pattern_match (XVECEXP (elem->data, 1, j),
2375 XVECEXP (subst_elem->data, 1, j),
2376 subst_elem->loc))
2378 patterns_match = 0;
2379 break;
2382 if (!get_alternatives_number (XVECEXP (elem->data, 1, j),
2383 &alternatives, subst_elem->loc))
2385 patterns_match = 0;
2386 break;
2390 /* Check if numbers of alternatives are the same in all
2391 match_operands in output template of define_subst. */
2392 for (j = 0; j < XVECLEN (subst_elem->data, 3); j++)
2394 if (!get_alternatives_number (XVECEXP (subst_elem->data, 3, j),
2395 &alternatives_subst,
2396 subst_elem->loc))
2398 patterns_match = 0;
2399 break;
2403 if (!patterns_match)
2404 continue;
2406 /* Clear array in which we save occupied indexes of operands. */
2407 memset (used_operands_numbers, 0, sizeof (used_operands_numbers));
2409 /* Create a pattern, based on the output one from define_subst. */
2410 subst_pattern_vec = rtvec_alloc (XVECLEN (subst_elem->data, 3));
2411 for (j = 0; j < XVECLEN (subst_elem->data, 3); j++)
2413 subst_pattern = copy_rtx (XVECEXP (subst_elem->data, 3, j));
2415 /* Duplicate constraints in substitute-pattern. */
2416 subst_pattern = alter_constraints (subst_pattern, alternatives,
2417 duplicate_each_alternative);
2419 subst_pattern = adjust_operands_numbers (subst_pattern);
2421 /* Substitute match_dup and match_op_dup in the new pattern and
2422 duplicate constraints. */
2423 subst_pattern = subst_dup (subst_pattern, alternatives,
2424 alternatives_subst);
2426 replace_duplicating_operands_in_pattern (subst_pattern);
2428 /* We don't need any constraints in DEFINE_EXPAND. */
2429 if (GET_CODE (elem->data) == DEFINE_EXPAND)
2430 remove_constraints (subst_pattern);
2432 RTVEC_ELT (subst_pattern_vec, j) = subst_pattern;
2434 XVEC (elem->data, 1) = subst_pattern_vec;
2436 for (i = 0; i < MAX_OPERANDS; i++)
2437 match_operand_entries_in_pattern[i] = NULL;
2439 if (GET_CODE (elem->data) == DEFINE_INSN)
2441 XTMPL (elem->data, 3) =
2442 alter_output_for_subst_insn (elem->data, alternatives_subst);
2443 alter_attrs_for_subst_insn (elem, alternatives_subst);
2446 /* Recalculate condition, joining conditions from original and
2447 DEFINE_SUBST input patterns. */
2448 XSTR (elem->data, 2)
2449 = rtx_reader_ptr->join_c_conditions (XSTR (subst_elem->data, 2),
2450 XSTR (elem->data, 2));
2451 /* Mark that subst was applied by changing attribute from "yes"
2452 to "no". */
2453 change_subst_attribute (elem, subst_elem, subst_false);
2456 /* If ELEM contains a subst attribute with value "yes", then we
2457 expected that a subst would be applied, but it wasn't - so,
2458 we need to remove that elementto avoid duplicating. */
2459 for (subst_elem = define_subst_queue;
2460 subst_elem; subst_elem = subst_elem->next)
2462 if (has_subst_attribute (elem, subst_elem))
2464 remove_from_queue (elem, &queue);
2465 return;
2470 /* This is a subroutine of mark_operands_used_in_match_dup.
2471 This routine is marks all MATCH_OPERANDs inside PATTERN as occupied. */
2472 static void
2473 mark_operands_from_match_dup (rtx pattern)
2475 const char *fmt;
2476 int i, j, len, opno;
2478 if (GET_CODE (pattern) == MATCH_OPERAND
2479 || GET_CODE (pattern) == MATCH_OPERATOR
2480 || GET_CODE (pattern) == MATCH_PARALLEL)
2482 opno = XINT (pattern, 0);
2483 gcc_assert (opno >= 0 && opno < MAX_OPERANDS);
2484 used_operands_numbers [opno] = 1;
2486 fmt = GET_RTX_FORMAT (GET_CODE (pattern));
2487 len = GET_RTX_LENGTH (GET_CODE (pattern));
2488 for (i = 0; i < len; i++)
2490 switch (fmt[i])
2492 case 'e': case 'u':
2493 mark_operands_from_match_dup (XEXP (pattern, i));
2494 break;
2495 case 'E':
2496 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
2497 mark_operands_from_match_dup (XVECEXP (pattern, i, j));
2498 break;
2503 /* This is a subroutine of adjust_operands_numbers.
2504 It goes through all expressions in PATTERN and when MATCH_DUP is
2505 met, all MATCH_OPERANDs inside it is marked as occupied. The
2506 process of marking is done by routin mark_operands_from_match_dup. */
2507 static void
2508 mark_operands_used_in_match_dup (rtx pattern)
2510 const char *fmt;
2511 int i, j, len, opno;
2513 if (GET_CODE (pattern) == MATCH_DUP)
2515 opno = XINT (pattern, 0);
2516 gcc_assert (opno >= 0 && opno < MAX_OPERANDS);
2517 mark_operands_from_match_dup (operand_data[opno]);
2518 return;
2520 fmt = GET_RTX_FORMAT (GET_CODE (pattern));
2521 len = GET_RTX_LENGTH (GET_CODE (pattern));
2522 for (i = 0; i < len; i++)
2524 switch (fmt[i])
2526 case 'e': case 'u':
2527 mark_operands_used_in_match_dup (XEXP (pattern, i));
2528 break;
2529 case 'E':
2530 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
2531 mark_operands_used_in_match_dup (XVECEXP (pattern, i, j));
2532 break;
2537 /* This is subroutine of renumerate_operands_in_pattern.
2538 It finds first not-occupied operand-index. */
2539 static int
2540 find_first_unused_number_of_operand ()
2542 int i;
2543 for (i = 0; i < MAX_OPERANDS; i++)
2544 if (!used_operands_numbers[i])
2545 return i;
2546 return MAX_OPERANDS;
2549 /* This is subroutine of adjust_operands_numbers.
2550 It visits all expressions in PATTERN and assigns not-occupied
2551 operand indexes to MATCH_OPERANDs and MATCH_OPERATORs of this
2552 PATTERN. */
2553 static void
2554 renumerate_operands_in_pattern (rtx pattern)
2556 const char *fmt;
2557 enum rtx_code code;
2558 int i, j, len, new_opno;
2559 code = GET_CODE (pattern);
2561 if (code == MATCH_OPERAND
2562 || code == MATCH_OPERATOR)
2564 new_opno = find_first_unused_number_of_operand ();
2565 gcc_assert (new_opno >= 0 && new_opno < MAX_OPERANDS);
2566 XINT (pattern, 0) = new_opno;
2567 used_operands_numbers [new_opno] = 1;
2570 fmt = GET_RTX_FORMAT (GET_CODE (pattern));
2571 len = GET_RTX_LENGTH (GET_CODE (pattern));
2572 for (i = 0; i < len; i++)
2574 switch (fmt[i])
2576 case 'e': case 'u':
2577 renumerate_operands_in_pattern (XEXP (pattern, i));
2578 break;
2579 case 'E':
2580 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
2581 renumerate_operands_in_pattern (XVECEXP (pattern, i, j));
2582 break;
2587 /* If output pattern of define_subst contains MATCH_DUP, then this
2588 expression would be replaced with the pattern, matched with
2589 MATCH_OPERAND from input pattern. This pattern could contain any
2590 number of MATCH_OPERANDs, MATCH_OPERATORs etc., so it's possible
2591 that a MATCH_OPERAND from output_pattern (if any) would have the
2592 same number, as MATCH_OPERAND from copied pattern. To avoid such
2593 indexes overlapping, we assign new indexes to MATCH_OPERANDs,
2594 laying in the output pattern outside of MATCH_DUPs. */
2595 static rtx
2596 adjust_operands_numbers (rtx pattern)
2598 mark_operands_used_in_match_dup (pattern);
2600 renumerate_operands_in_pattern (pattern);
2602 return pattern;
2605 /* Generate RTL expression
2606 (match_dup OPNO)
2608 static rtx
2609 generate_match_dup (int opno)
2611 rtx return_rtx = rtx_alloc (MATCH_DUP);
2612 PUT_CODE (return_rtx, MATCH_DUP);
2613 XINT (return_rtx, 0) = opno;
2614 return return_rtx;
2617 /* This routine checks all match_operands in PATTERN and if some of
2618 have the same index, it replaces all of them except the first one to
2619 match_dup.
2620 Usually, match_operands with the same indexes are forbidden, but
2621 after define_subst copy an RTL-expression from original template,
2622 indexes of existed and just-copied match_operands could coincide.
2623 To fix it, we replace one of them with match_dup. */
2624 static rtx
2625 replace_duplicating_operands_in_pattern (rtx pattern)
2627 const char *fmt;
2628 int i, j, len, opno;
2629 rtx mdup;
2631 if (GET_CODE (pattern) == MATCH_OPERAND)
2633 opno = XINT (pattern, 0);
2634 gcc_assert (opno >= 0 && opno < MAX_OPERANDS);
2635 if (match_operand_entries_in_pattern[opno] == NULL)
2637 match_operand_entries_in_pattern[opno] = pattern;
2638 return NULL;
2640 else
2642 /* Compare predicates before replacing with match_dup. */
2643 if (strcmp (XSTR (pattern, 1),
2644 XSTR (match_operand_entries_in_pattern[opno], 1)))
2646 error ("duplicated match_operands with different predicates were"
2647 " found.");
2648 return NULL;
2650 return generate_match_dup (opno);
2653 fmt = GET_RTX_FORMAT (GET_CODE (pattern));
2654 len = GET_RTX_LENGTH (GET_CODE (pattern));
2655 for (i = 0; i < len; i++)
2657 switch (fmt[i])
2659 case 'e': case 'u':
2660 mdup = replace_duplicating_operands_in_pattern (XEXP (pattern, i));
2661 if (mdup)
2662 XEXP (pattern, i) = mdup;
2663 break;
2664 case 'E':
2665 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
2667 mdup =
2668 replace_duplicating_operands_in_pattern (XVECEXP
2669 (pattern, i, j));
2670 if (mdup)
2671 XVECEXP (pattern, i, j) = mdup;
2673 break;
2676 return NULL;
2679 /* The routine modifies given input PATTERN of define_subst, replacing
2680 MATCH_DUP and MATCH_OP_DUP with operands from define_insn original
2681 pattern, whose operands are stored in OPERAND_DATA array.
2682 It also duplicates constraints in operands - constraints from
2683 define_insn operands are duplicated N_SUBST_ALT times, constraints
2684 from define_subst operands are duplicated N_ALT times.
2685 After the duplication, returned output rtl-pattern contains every
2686 combination of input constraints Vs constraints from define_subst
2687 output. */
2688 static rtx
2689 subst_dup (rtx pattern, int n_alt, int n_subst_alt)
2691 const char *fmt;
2692 enum rtx_code code;
2693 int i, j, len, opno;
2695 code = GET_CODE (pattern);
2696 switch (code)
2698 case MATCH_DUP:
2699 case MATCH_OP_DUP:
2700 opno = XINT (pattern, 0);
2702 gcc_assert (opno >= 0 && opno < MAX_OPERANDS);
2704 if (operand_data[opno])
2706 pattern = copy_rtx (operand_data[opno]);
2708 /* Duplicate constraints. */
2709 pattern = alter_constraints (pattern, n_subst_alt,
2710 duplicate_alternatives);
2712 break;
2714 default:
2715 break;
2718 fmt = GET_RTX_FORMAT (GET_CODE (pattern));
2719 len = GET_RTX_LENGTH (GET_CODE (pattern));
2720 for (i = 0; i < len; i++)
2722 switch (fmt[i])
2724 case 'e': case 'u':
2725 if (code != MATCH_DUP && code != MATCH_OP_DUP)
2726 XEXP (pattern, i) = subst_dup (XEXP (pattern, i),
2727 n_alt, n_subst_alt);
2728 break;
2729 case 'V':
2730 if (XVEC (pattern, i) == NULL)
2731 break;
2732 /* FALLTHRU */
2733 case 'E':
2734 if (code != MATCH_DUP && code != MATCH_OP_DUP)
2735 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
2736 XVECEXP (pattern, i, j) = subst_dup (XVECEXP (pattern, i, j),
2737 n_alt, n_subst_alt);
2738 break;
2740 case 'r': case 'p': case 'i': case 'w':
2741 case '0': case 's': case 'S': case 'T':
2742 break;
2744 default:
2745 gcc_unreachable ();
2748 return pattern;
2751 /* If we have any DEFINE_COND_EXEC patterns, expand the DEFINE_INSN
2752 patterns appropriately. */
2754 static void
2755 process_define_cond_exec (void)
2757 class queue_elem *elem;
2759 identify_predicable_attribute ();
2760 if (have_error)
2761 return;
2763 for (elem = define_cond_exec_queue; elem ; elem = elem->next)
2764 process_one_cond_exec (elem);
2767 /* If we have any DEFINE_SUBST patterns, expand DEFINE_INSN and
2768 DEFINE_EXPAND patterns appropriately. */
2770 static void
2771 process_define_subst (void)
2773 class queue_elem *elem, *elem_attr;
2775 /* Check if each define_subst has corresponding define_subst_attr. */
2776 for (elem = define_subst_queue; elem ; elem = elem->next)
2778 for (elem_attr = define_subst_attr_queue;
2779 elem_attr;
2780 elem_attr = elem_attr->next)
2781 if (strcmp (XSTR (elem->data, 0), XSTR (elem_attr->data, 1)) == 0)
2782 goto found;
2784 error_at (elem->loc,
2785 "%s: `define_subst' must have at least one "
2786 "corresponding `define_subst_attr'",
2787 XSTR (elem->data, 0));
2788 return;
2790 found:
2791 continue;
2794 for (elem = define_insn_queue; elem ; elem = elem->next)
2795 process_substs_on_one_elem (elem, define_insn_queue);
2796 for (elem = other_queue; elem ; elem = elem->next)
2798 if (GET_CODE (elem->data) != DEFINE_EXPAND)
2799 continue;
2800 process_substs_on_one_elem (elem, other_queue);
2804 /* A subclass of rtx_reader which reads .md files and calls process_rtx on
2805 the top-level elements. */
2807 class gen_reader : public rtx_reader
2809 public:
2810 gen_reader () : rtx_reader (false) {}
2811 void handle_unknown_directive (file_location, const char *) final override;
2814 void
2815 gen_reader::handle_unknown_directive (file_location loc, const char *rtx_name)
2817 auto_vec<rtx, 32> subrtxs;
2818 if (!read_rtx (rtx_name, &subrtxs))
2819 return;
2821 rtx x;
2822 unsigned int i;
2823 FOR_EACH_VEC_ELT (subrtxs, i, x)
2824 process_rtx (x, loc);
2827 /* Add mnemonic STR with length LEN to the mnemonic hash table
2828 MNEMONIC_HTAB. A trailing zero end character is appended to STR
2829 and a permanent heap copy of STR is created. */
2831 static void
2832 add_mnemonic_string (htab_t mnemonic_htab, const char *str, size_t len)
2834 char *new_str;
2835 void **slot;
2836 char *str_zero = (char*)alloca (len + 1);
2838 memcpy (str_zero, str, len);
2839 str_zero[len] = '\0';
2841 slot = htab_find_slot (mnemonic_htab, str_zero, INSERT);
2843 if (*slot)
2844 return;
2846 /* Not found; create a permanent copy and add it to the hash table. */
2847 new_str = XNEWVAR (char, len + 1);
2848 memcpy (new_str, str_zero, len + 1);
2849 *slot = new_str;
2852 /* Scan INSN for mnemonic strings and add them to the mnemonic hash
2853 table in MNEMONIC_HTAB.
2855 The mnemonics cannot be found if they are emitted using C code.
2857 If a mnemonic string contains ';' or a newline the string assumed
2858 to consist of more than a single instruction. The attribute value
2859 will then be set to the user defined default value. */
2861 static void
2862 gen_mnemonic_setattr (htab_t mnemonic_htab, rtx insn)
2864 const char *template_code, *cp;
2865 int i;
2866 int vec_len;
2867 rtx set_attr;
2868 char *attr_name;
2869 rtvec new_vec;
2870 struct obstack *string_obstack = rtx_reader_ptr->get_string_obstack ();
2872 template_code = XTMPL (insn, 3);
2874 /* Skip patterns which use C code to emit the template. */
2875 if (template_code[0] == '*')
2876 return;
2878 if (template_code[0] == '@')
2879 cp = &template_code[1];
2880 else
2881 cp = &template_code[0];
2883 for (i = 0; *cp; )
2885 const char *ep, *sp;
2886 size_t size = 0;
2888 while (ISSPACE (*cp))
2889 cp++;
2891 for (ep = sp = cp; !IS_VSPACE (*ep) && *ep != '\0'; ++ep)
2892 if (!ISSPACE (*ep))
2893 sp = ep + 1;
2895 if (i > 0)
2896 obstack_1grow (string_obstack, ',');
2898 while (cp < sp && ((*cp >= '0' && *cp <= '9')
2899 || (*cp >= 'a' && *cp <= 'z')))
2902 obstack_1grow (string_obstack, *cp);
2903 cp++;
2904 size++;
2907 while (cp < sp)
2909 if (*cp == ';' || (*cp == '\\' && cp[1] == 'n'))
2911 /* Don't set a value if there are more than one
2912 instruction in the string. */
2913 obstack_blank_fast (string_obstack, -size);
2914 size = 0;
2916 cp = sp;
2917 break;
2919 cp++;
2921 if (size == 0)
2922 obstack_1grow (string_obstack, '*');
2923 else
2924 add_mnemonic_string (mnemonic_htab,
2925 (char *) obstack_next_free (string_obstack) - size,
2926 size);
2927 i++;
2930 /* An insn definition might emit an empty string. */
2931 if (obstack_object_size (string_obstack) == 0)
2932 return;
2934 obstack_1grow (string_obstack, '\0');
2936 set_attr = rtx_alloc (SET_ATTR);
2937 XSTR (set_attr, 1) = XOBFINISH (string_obstack, char *);
2938 attr_name = XNEWVAR (char, strlen (MNEMONIC_ATTR_NAME) + 1);
2939 strcpy (attr_name, MNEMONIC_ATTR_NAME);
2940 XSTR (set_attr, 0) = attr_name;
2942 if (!XVEC (insn, 4))
2943 vec_len = 0;
2944 else
2945 vec_len = XVECLEN (insn, 4);
2947 new_vec = rtvec_alloc (vec_len + 1);
2948 for (i = 0; i < vec_len; i++)
2949 RTVEC_ELT (new_vec, i) = XVECEXP (insn, 4, i);
2950 RTVEC_ELT (new_vec, vec_len) = set_attr;
2951 XVEC (insn, 4) = new_vec;
2954 /* This function is called for the elements in the mnemonic hashtable
2955 and generates a comma separated list of the mnemonics. */
2957 static int
2958 mnemonic_htab_callback (void **slot, void *info ATTRIBUTE_UNUSED)
2960 struct obstack *string_obstack = rtx_reader_ptr->get_string_obstack ();
2962 obstack_grow (string_obstack, (char*) *slot, strlen ((char*) *slot));
2963 obstack_1grow (string_obstack, ',');
2964 return 1;
2967 /* Generate (set_attr "mnemonic" "..") RTXs and append them to every
2968 insn definition in case the back end requests it by defining the
2969 mnemonic attribute. The values for the attribute will be extracted
2970 from the output patterns of the insn definitions as far as
2971 possible. */
2973 static void
2974 gen_mnemonic_attr (void)
2976 class queue_elem *elem;
2977 rtx mnemonic_attr = NULL;
2978 htab_t mnemonic_htab;
2979 const char *str, *p;
2980 int i;
2981 struct obstack *string_obstack = rtx_reader_ptr->get_string_obstack ();
2983 if (have_error)
2984 return;
2986 /* Look for the DEFINE_ATTR for `mnemonic'. */
2987 for (elem = define_attr_queue; elem != *define_attr_tail; elem = elem->next)
2988 if (GET_CODE (elem->data) == DEFINE_ATTR
2989 && strcmp (XSTR (elem->data, 0), MNEMONIC_ATTR_NAME) == 0)
2991 mnemonic_attr = elem->data;
2992 break;
2995 /* A (define_attr "mnemonic" "...") indicates that the back-end
2996 wants a mnemonic attribute to be generated. */
2997 if (!mnemonic_attr)
2998 return;
3000 mnemonic_htab = htab_create_alloc (MNEMONIC_HTAB_SIZE, htab_hash_string,
3001 htab_eq_string, 0, xcalloc, free);
3003 for (elem = define_insn_queue; elem; elem = elem->next)
3005 rtx insn = elem->data;
3006 bool found = false;
3008 /* Check if the insn definition already has
3009 (set_attr "mnemonic" ...) or (set (attr "mnemonic") ...). */
3010 if (XVEC (insn, 4))
3011 for (i = 0; i < XVECLEN (insn, 4); i++)
3013 rtx set_attr = XVECEXP (insn, 4, i);
3015 switch (GET_CODE (set_attr))
3017 case SET_ATTR:
3018 case SET_ATTR_ALTERNATIVE:
3019 if (strcmp (XSTR (set_attr, 0), MNEMONIC_ATTR_NAME) == 0)
3020 found = true;
3021 break;
3022 case SET:
3023 if (GET_CODE (SET_DEST (set_attr)) == ATTR
3024 && strcmp (XSTR (SET_DEST (set_attr), 0),
3025 MNEMONIC_ATTR_NAME) == 0)
3026 found = true;
3027 break;
3028 default:
3029 break;
3033 if (!found)
3034 gen_mnemonic_setattr (mnemonic_htab, insn);
3037 /* Add the user defined values to the hash table. */
3038 str = XSTR (mnemonic_attr, 1);
3039 while ((p = scan_comma_elt (&str)) != NULL)
3040 add_mnemonic_string (mnemonic_htab, p, str - p);
3042 htab_traverse (mnemonic_htab, mnemonic_htab_callback, NULL);
3044 /* Replace the last ',' with the zero end character. */
3045 *((char *) obstack_next_free (string_obstack) - 1) = '\0';
3046 XSTR (mnemonic_attr, 1) = XOBFINISH (string_obstack, char *);
3049 /* Check if there are DEFINE_ATTRs with the same name. */
3050 static void
3051 check_define_attr_duplicates ()
3053 class queue_elem *elem;
3054 htab_t attr_htab;
3055 char * attr_name;
3056 void **slot;
3058 attr_htab = htab_create (500, htab_hash_string, htab_eq_string, NULL);
3060 for (elem = define_attr_queue; elem; elem = elem->next)
3062 attr_name = xstrdup (XSTR (elem->data, 0));
3064 slot = htab_find_slot (attr_htab, attr_name, INSERT);
3066 /* Duplicate. */
3067 if (*slot)
3069 error_at (elem->loc, "redefinition of attribute '%s'", attr_name);
3070 htab_delete (attr_htab);
3071 return;
3074 *slot = attr_name;
3077 htab_delete (attr_htab);
3080 /* The entry point for initializing the reader. */
3082 rtx_reader *
3083 init_rtx_reader_args_cb (int argc, const char **argv,
3084 bool (*parse_opt) (const char *))
3086 /* Prepare to read input. */
3087 condition_table = htab_create (500, hash_c_test, cmp_c_test, NULL);
3088 init_predicate_table ();
3089 obstack_init (rtl_obstack);
3091 /* Start at 1, to make 0 available for CODE_FOR_nothing. */
3092 insn_sequence_num = 1;
3094 /* These sequences are not used as indices, so can start at 1 also. */
3095 split_sequence_num = 1;
3096 peephole2_sequence_num = 1;
3098 gen_reader *reader = new gen_reader ();
3099 reader->read_md_files (argc, argv, parse_opt);
3101 if (define_attr_queue != NULL)
3102 check_define_attr_duplicates ();
3104 /* Process define_cond_exec patterns. */
3105 if (define_cond_exec_queue != NULL)
3106 process_define_cond_exec ();
3108 /* Process define_subst patterns. */
3109 if (define_subst_queue != NULL)
3110 process_define_subst ();
3112 if (define_attr_queue != NULL)
3113 gen_mnemonic_attr ();
3115 if (have_error)
3117 delete reader;
3118 return NULL;
3121 return reader;
3124 /* Programs that don't have their own options can use this entry point
3125 instead. */
3126 rtx_reader *
3127 init_rtx_reader_args (int argc, const char **argv)
3129 return init_rtx_reader_args_cb (argc, argv, 0);
3132 /* Try to read a single rtx from the file. Return true on success,
3133 describing it in *INFO. */
3135 bool
3136 read_md_rtx (md_rtx_info *info)
3138 int truth, *counter;
3139 rtx def;
3141 /* Discard insn patterns which we know can never match (because
3142 their C test is provably always false). If insn_elision is
3143 false, our caller needs to see all the patterns. Note that the
3144 elided patterns are never counted by the sequence numbering; it
3145 is the caller's responsibility, when insn_elision is false, not
3146 to use elided pattern numbers for anything. */
3149 class queue_elem **queue, *elem;
3151 /* Read all patterns from a given queue before moving on to the next. */
3152 if (define_attr_queue != NULL)
3153 queue = &define_attr_queue;
3154 else if (define_pred_queue != NULL)
3155 queue = &define_pred_queue;
3156 else if (define_insn_queue != NULL)
3157 queue = &define_insn_queue;
3158 else if (other_queue != NULL)
3159 queue = &other_queue;
3160 else
3161 return false;
3163 elem = *queue;
3164 *queue = elem->next;
3165 def = elem->data;
3166 info->def = def;
3167 info->loc = elem->loc;
3168 free (elem);
3170 truth = maybe_eval_c_test (get_c_test (def));
3172 while (truth == 0 && insn_elision);
3174 /* Perform code-specific processing and pick the appropriate sequence
3175 number counter. */
3176 switch (GET_CODE (def))
3178 case DEFINE_INSN:
3179 case DEFINE_EXPAND:
3180 /* insn_sequence_num is used here so the name table will match caller's
3181 idea of insn numbering, whether or not elision is active. */
3182 record_insn_name (insn_sequence_num, XSTR (def, 0));
3184 /* Fall through. */
3185 case DEFINE_PEEPHOLE:
3186 counter = &insn_sequence_num;
3187 break;
3189 case DEFINE_SPLIT:
3190 counter = &split_sequence_num;
3191 break;
3193 case DEFINE_PEEPHOLE2:
3194 counter = &peephole2_sequence_num;
3195 break;
3197 default:
3198 counter = NULL;
3199 break;
3202 if (counter)
3204 info->index = *counter;
3205 if (truth != 0)
3206 *counter += 1;
3208 else
3209 info->index = -1;
3211 if (!rtx_locs)
3212 rtx_locs = new hash_map <rtx, file_location>;
3213 rtx_locs->put (info->def, info->loc);
3215 return true;
3218 /* Return the file location of DEFINE_* rtx X, which was previously
3219 returned by read_md_rtx. */
3220 file_location
3221 get_file_location (rtx x)
3223 gcc_assert (rtx_locs);
3224 file_location *entry = rtx_locs->get (x);
3225 gcc_assert (entry);
3226 return *entry;
3229 /* Return the number of possible INSN_CODEs. Only meaningful once the
3230 whole file has been processed. */
3231 unsigned int
3232 get_num_insn_codes ()
3234 return insn_sequence_num;
3237 /* Return the C test that says whether definition rtx DEF can be used,
3238 or "" if it can be used unconditionally. */
3240 const char *
3241 get_c_test (rtx x)
3243 switch (GET_CODE (x))
3245 case DEFINE_INSN:
3246 case DEFINE_EXPAND:
3247 case DEFINE_SUBST:
3248 return XSTR (x, 2);
3250 case DEFINE_SPLIT:
3251 case DEFINE_PEEPHOLE:
3252 case DEFINE_PEEPHOLE2:
3253 return XSTR (x, 1);
3255 default:
3256 return "";
3260 /* Helper functions for insn elision. */
3262 /* Compute a hash function of a c_test structure, which is keyed
3263 by its ->expr field. */
3264 hashval_t
3265 hash_c_test (const void *x)
3267 const struct c_test *a = (const struct c_test *) x;
3268 const unsigned char *base, *s = (const unsigned char *) a->expr;
3269 hashval_t hash;
3270 unsigned char c;
3271 unsigned int len;
3273 base = s;
3274 hash = 0;
3276 while ((c = *s++) != '\0')
3278 hash += c + (c << 17);
3279 hash ^= hash >> 2;
3282 len = s - base;
3283 hash += len + (len << 17);
3284 hash ^= hash >> 2;
3286 return hash;
3289 /* Compare two c_test expression structures. */
3291 cmp_c_test (const void *x, const void *y)
3293 const struct c_test *a = (const struct c_test *) x;
3294 const struct c_test *b = (const struct c_test *) y;
3296 return !strcmp (a->expr, b->expr);
3299 /* Given a string representing a C test expression, look it up in the
3300 condition_table and report whether or not its value is known
3301 at compile time. Returns a tristate: 1 for known true, 0 for
3302 known false, -1 for unknown. */
3304 maybe_eval_c_test (const char *expr)
3306 const struct c_test *test;
3307 struct c_test dummy;
3309 if (expr[0] == 0)
3310 return 1;
3312 dummy.expr = expr;
3313 test = (const struct c_test *)htab_find (condition_table, &dummy);
3314 if (!test)
3315 return -1;
3316 return test->value;
3319 /* Record the C test expression EXPR in the condition_table, with
3320 value VAL. Duplicates clobber previous entries. */
3322 void
3323 add_c_test (const char *expr, int value)
3325 struct c_test *test;
3327 if (expr[0] == 0)
3328 return;
3330 test = XNEW (struct c_test);
3331 test->expr = expr;
3332 test->value = value;
3334 *(htab_find_slot (condition_table, test, INSERT)) = test;
3337 /* For every C test, call CALLBACK with two arguments: a pointer to
3338 the condition structure and INFO. Stops when CALLBACK returns zero. */
3339 void
3340 traverse_c_tests (htab_trav callback, void *info)
3342 if (condition_table)
3343 htab_traverse (condition_table, callback, info);
3346 /* Helper functions for define_predicate and define_special_predicate
3347 processing. Shared between genrecog.cc and genpreds.cc. */
3349 static htab_t predicate_table;
3350 struct pred_data *first_predicate;
3351 static struct pred_data **last_predicate = &first_predicate;
3353 static hashval_t
3354 hash_struct_pred_data (const void *ptr)
3356 return htab_hash_string (((const struct pred_data *)ptr)->name);
3359 static int
3360 eq_struct_pred_data (const void *a, const void *b)
3362 return !strcmp (((const struct pred_data *)a)->name,
3363 ((const struct pred_data *)b)->name);
3366 struct pred_data *
3367 lookup_predicate (const char *name)
3369 struct pred_data key;
3370 key.name = name;
3371 return (struct pred_data *) htab_find (predicate_table, &key);
3374 /* Record that predicate PRED can accept CODE. */
3376 void
3377 add_predicate_code (struct pred_data *pred, enum rtx_code code)
3379 if (!pred->codes[code])
3381 pred->num_codes++;
3382 pred->codes[code] = true;
3384 if (GET_RTX_CLASS (code) != RTX_CONST_OBJ)
3385 pred->allows_non_const = true;
3387 if (code != REG
3388 && code != SUBREG
3389 && code != MEM
3390 && code != CONCAT
3391 && code != PARALLEL
3392 && code != STRICT_LOW_PART
3393 && code != ZERO_EXTRACT
3394 && code != SCRATCH)
3395 pred->allows_non_lvalue = true;
3397 if (pred->num_codes == 1)
3398 pred->singleton = code;
3399 else if (pred->num_codes == 2)
3400 pred->singleton = UNKNOWN;
3404 void
3405 add_predicate (struct pred_data *pred)
3407 void **slot = htab_find_slot (predicate_table, pred, INSERT);
3408 if (*slot)
3410 error ("duplicate predicate definition for '%s'", pred->name);
3411 return;
3413 *slot = pred;
3414 *last_predicate = pred;
3415 last_predicate = &pred->next;
3418 /* This array gives the initial content of the predicate table. It
3419 has entries for all predicates defined in recog.cc. */
3421 struct std_pred_table
3423 const char *name;
3424 bool special;
3425 bool allows_const_p;
3426 RTX_CODE codes[NUM_RTX_CODE];
3429 static const struct std_pred_table std_preds[] = {
3430 {"general_operand", false, true, {SUBREG, REG, MEM}},
3431 {"address_operand", true, true, {SUBREG, REG, MEM, PLUS, MINUS, MULT,
3432 ZERO_EXTEND, SIGN_EXTEND, AND}},
3433 {"register_operand", false, false, {SUBREG, REG}},
3434 {"pmode_register_operand", true, false, {SUBREG, REG}},
3435 {"scratch_operand", false, false, {SCRATCH, REG}},
3436 {"immediate_operand", false, true, {UNKNOWN}},
3437 {"const_int_operand", false, false, {CONST_INT}},
3438 #if TARGET_SUPPORTS_WIDE_INT
3439 {"const_scalar_int_operand", false, false, {CONST_INT, CONST_WIDE_INT}},
3440 {"const_double_operand", false, false, {CONST_DOUBLE}},
3441 #else
3442 {"const_double_operand", false, false, {CONST_INT, CONST_DOUBLE}},
3443 #endif
3444 {"nonimmediate_operand", false, false, {SUBREG, REG, MEM}},
3445 {"nonmemory_operand", false, true, {SUBREG, REG}},
3446 {"push_operand", false, false, {MEM}},
3447 {"pop_operand", false, false, {MEM}},
3448 {"memory_operand", false, false, {SUBREG, MEM}},
3449 {"indirect_operand", false, false, {SUBREG, MEM}},
3450 {"ordered_comparison_operator", false, false, {EQ, NE,
3451 LE, LT, GE, GT,
3452 LEU, LTU, GEU, GTU}},
3453 {"comparison_operator", false, false, {EQ, NE,
3454 LE, LT, GE, GT,
3455 LEU, LTU, GEU, GTU,
3456 UNORDERED, ORDERED,
3457 UNEQ, UNGE, UNGT,
3458 UNLE, UNLT, LTGT}}
3460 #define NUM_KNOWN_STD_PREDS ARRAY_SIZE (std_preds)
3462 /* Initialize the table of predicate definitions, starting with
3463 the information we have on generic predicates. */
3465 static void
3466 init_predicate_table (void)
3468 size_t i, j;
3469 struct pred_data *pred;
3471 predicate_table = htab_create_alloc (37, hash_struct_pred_data,
3472 eq_struct_pred_data, 0,
3473 xcalloc, free);
3475 for (i = 0; i < NUM_KNOWN_STD_PREDS; i++)
3477 pred = XCNEW (struct pred_data);
3478 pred->name = std_preds[i].name;
3479 pred->special = std_preds[i].special;
3481 for (j = 0; std_preds[i].codes[j] != 0; j++)
3482 add_predicate_code (pred, std_preds[i].codes[j]);
3484 if (std_preds[i].allows_const_p)
3485 for (j = 0; j < NUM_RTX_CODE; j++)
3486 if (GET_RTX_CLASS (j) == RTX_CONST_OBJ)
3487 add_predicate_code (pred, (enum rtx_code) j);
3489 add_predicate (pred);
3493 /* These functions allow linkage with print-rtl.cc. Also, some generators
3494 like to annotate their output with insn names. */
3496 /* Holds an array of names indexed by insn_code_number. */
3497 static char **insn_name_ptr = 0;
3498 static int insn_name_ptr_size = 0;
3500 const char *
3501 get_insn_name (int code)
3503 if (code < insn_name_ptr_size)
3504 return insn_name_ptr[code];
3505 else
3506 return NULL;
3509 static void
3510 record_insn_name (int code, const char *name)
3512 static const char *last_real_name = "insn";
3513 static int last_real_code = 0;
3514 char *new_name;
3516 if (insn_name_ptr_size <= code)
3518 int new_size;
3519 new_size = (insn_name_ptr_size ? insn_name_ptr_size * 2 : 512);
3520 insn_name_ptr = XRESIZEVEC (char *, insn_name_ptr, new_size);
3521 memset (insn_name_ptr + insn_name_ptr_size, 0,
3522 sizeof (char *) * (new_size - insn_name_ptr_size));
3523 insn_name_ptr_size = new_size;
3526 if (!name || name[0] == '\0')
3528 new_name = XNEWVAR (char, strlen (last_real_name) + 10);
3529 sprintf (new_name, "%s+%d", last_real_name, code - last_real_code);
3531 else
3533 last_real_name = new_name = xstrdup (name);
3534 last_real_code = code;
3537 insn_name_ptr[code] = new_name;
3540 /* Make STATS describe the operands that appear in rtx X. */
3542 static void
3543 get_pattern_stats_1 (struct pattern_stats *stats, rtx x)
3545 RTX_CODE code;
3546 int i;
3547 int len;
3548 const char *fmt;
3550 if (x == NULL_RTX)
3551 return;
3553 code = GET_CODE (x);
3554 switch (code)
3556 case MATCH_OPERAND:
3557 case MATCH_OPERATOR:
3558 case MATCH_PARALLEL:
3559 stats->max_opno = MAX (stats->max_opno, XINT (x, 0));
3560 break;
3562 case MATCH_DUP:
3563 case MATCH_OP_DUP:
3564 case MATCH_PAR_DUP:
3565 stats->num_dups++;
3566 stats->max_dup_opno = MAX (stats->max_dup_opno, XINT (x, 0));
3567 break;
3569 case MATCH_SCRATCH:
3570 if (stats->min_scratch_opno == -1)
3571 stats->min_scratch_opno = XINT (x, 0);
3572 else
3573 stats->min_scratch_opno = MIN (stats->min_scratch_opno, XINT (x, 0));
3574 stats->max_scratch_opno = MAX (stats->max_scratch_opno, XINT (x, 0));
3575 break;
3577 default:
3578 break;
3581 fmt = GET_RTX_FORMAT (code);
3582 len = GET_RTX_LENGTH (code);
3583 for (i = 0; i < len; i++)
3585 if (fmt[i] == 'e' || fmt[i] == 'u')
3586 get_pattern_stats_1 (stats, XEXP (x, i));
3587 else if (fmt[i] == 'E')
3589 int j;
3590 for (j = 0; j < XVECLEN (x, i); j++)
3591 get_pattern_stats_1 (stats, XVECEXP (x, i, j));
3596 /* Make STATS describe the operands that appear in instruction pattern
3597 PATTERN. */
3599 void
3600 get_pattern_stats (struct pattern_stats *stats, rtvec pattern)
3602 int i, len;
3604 stats->max_opno = -1;
3605 stats->max_dup_opno = -1;
3606 stats->min_scratch_opno = -1;
3607 stats->max_scratch_opno = -1;
3608 stats->num_dups = 0;
3610 len = GET_NUM_ELEM (pattern);
3611 for (i = 0; i < len; i++)
3612 get_pattern_stats_1 (stats, RTVEC_ELT (pattern, i));
3614 stats->num_generator_args = stats->max_opno + 1;
3615 stats->num_insn_operands = MAX (stats->max_opno,
3616 stats->max_scratch_opno) + 1;
3617 stats->num_operand_vars = MAX (stats->max_opno,
3618 MAX (stats->max_dup_opno,
3619 stats->max_scratch_opno)) + 1;
3622 /* Return the emit_* function that should be used for pattern X, or NULL
3623 if we can't pick a particular type at compile time and should instead
3624 fall back to "emit". */
3626 const char *
3627 get_emit_function (rtx x)
3629 switch (classify_insn (x))
3631 case INSN:
3632 return "emit_insn";
3634 case CALL_INSN:
3635 return "emit_call_insn";
3637 case JUMP_INSN:
3638 return "emit_jump_insn";
3640 case UNKNOWN:
3641 return NULL;
3643 default:
3644 gcc_unreachable ();
3648 /* Return true if we must emit a barrier after pattern X. */
3650 bool
3651 needs_barrier_p (rtx x)
3653 return (GET_CODE (x) == SET
3654 && GET_CODE (SET_DEST (x)) == PC
3655 && GET_CODE (SET_SRC (x)) == LABEL_REF);
3658 #define NS "NULL"
3659 #define ZS "'\\0'"
3660 #define OPTAB_CL(o, p, c, b, l) { #o, p, #b, ZS, #l, o, c, UNKNOWN, 1 },
3661 #define OPTAB_CX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 1 },
3662 #define OPTAB_CD(o, p) { #o, p, NS, ZS, NS, o, UNKNOWN, UNKNOWN, 2 },
3663 #define OPTAB_NL(o, p, c, b, s, l) { #o, p, #b, #s, #l, o, c, c, 3 },
3664 #define OPTAB_NC(o, p, c) { #o, p, NS, ZS, NS, o, c, c, 3 },
3665 #define OPTAB_NX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 3 },
3666 #define OPTAB_VL(o, p, c, b, s, l) { #o, p, #b, #s, #l, o, c, UNKNOWN, 3 },
3667 #define OPTAB_VC(o, p, c) { #o, p, NS, ZS, NS, o, c, UNKNOWN, 3 },
3668 #define OPTAB_VX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 3 },
3669 #define OPTAB_DC(o, p, c) { #o, p, NS, ZS, NS, o, c, c, 4 },
3670 #define OPTAB_D(o, p) { #o, p, NS, ZS, NS, o, UNKNOWN, UNKNOWN, 4 },
3672 /* An array of all optabs. Note that the same optab can appear more
3673 than once, with a different pattern. */
3674 optab_def optabs[] = {
3675 { "unknown_optab", NULL, NS, ZS, NS, unknown_optab, UNKNOWN, UNKNOWN, 0 },
3676 #include "optabs.def"
3679 /* The number of entries in optabs[]. */
3680 unsigned int num_optabs = ARRAY_SIZE (optabs);
3682 #undef OPTAB_CL
3683 #undef OPTAB_CX
3684 #undef OPTAB_CD
3685 #undef OPTAB_NL
3686 #undef OPTAB_NC
3687 #undef OPTAB_NX
3688 #undef OPTAB_VL
3689 #undef OPTAB_VC
3690 #undef OPTAB_VX
3691 #undef OPTAB_DC
3692 #undef OPTAB_D
3694 /* Return true if instruction NAME matches pattern PAT, storing information
3695 about the match in P if so. */
3697 static bool
3698 match_pattern (optab_pattern *p, const char *name, const char *pat)
3700 bool force_float = false;
3701 bool force_int = false;
3702 bool force_partial_int = false;
3703 bool force_fixed = false;
3705 if (pat == NULL)
3706 return false;
3707 for (; ; ++pat)
3709 if (*pat != '$')
3711 if (*pat != *name++)
3712 return false;
3713 if (*pat == '\0')
3714 return true;
3715 continue;
3717 switch (*++pat)
3719 case 'I':
3720 force_int = 1;
3721 break;
3722 case 'P':
3723 force_partial_int = 1;
3724 break;
3725 case 'F':
3726 force_float = 1;
3727 break;
3728 case 'Q':
3729 force_fixed = 1;
3730 break;
3732 case 'a':
3733 case 'b':
3735 int i;
3737 /* This loop will stop at the first prefix match, so
3738 look through the modes in reverse order, in case
3739 there are extra CC modes and CC is a prefix of the
3740 CC modes (as it should be). */
3741 for (i = (MAX_MACHINE_MODE) - 1; i >= 0; i--)
3743 const char *p, *q;
3744 for (p = GET_MODE_NAME (i), q = name; *p; p++, q++)
3745 if (TOLOWER (*p) != *q)
3746 break;
3747 if (*p == 0
3748 && (! force_int || mode_class[i] == MODE_INT
3749 || mode_class[i] == MODE_VECTOR_INT)
3750 && (! force_partial_int
3751 || mode_class[i] == MODE_INT
3752 || mode_class[i] == MODE_PARTIAL_INT
3753 || mode_class[i] == MODE_VECTOR_INT)
3754 && (! force_float
3755 || mode_class[i] == MODE_FLOAT
3756 || mode_class[i] == MODE_DECIMAL_FLOAT
3757 || mode_class[i] == MODE_COMPLEX_FLOAT
3758 || mode_class[i] == MODE_VECTOR_FLOAT)
3759 && (! force_fixed
3760 || mode_class[i] == MODE_FRACT
3761 || mode_class[i] == MODE_UFRACT
3762 || mode_class[i] == MODE_ACCUM
3763 || mode_class[i] == MODE_UACCUM
3764 || mode_class[i] == MODE_VECTOR_FRACT
3765 || mode_class[i] == MODE_VECTOR_UFRACT
3766 || mode_class[i] == MODE_VECTOR_ACCUM
3767 || mode_class[i] == MODE_VECTOR_UACCUM))
3768 break;
3771 if (i < 0)
3772 return false;
3773 name += strlen (GET_MODE_NAME (i));
3774 if (*pat == 'a')
3775 p->m1 = i;
3776 else
3777 p->m2 = i;
3779 force_int = false;
3780 force_partial_int = false;
3781 force_float = false;
3782 force_fixed = false;
3784 break;
3786 default:
3787 gcc_unreachable ();
3792 /* Return true if NAME is the name of an optab, describing it in P if so. */
3794 bool
3795 find_optab (optab_pattern *p, const char *name)
3797 if (*name == 0 || *name == '*')
3798 return false;
3800 /* See if NAME matches one of the patterns we have for the optabs
3801 we know about. */
3802 for (unsigned int pindex = 0; pindex < ARRAY_SIZE (optabs); pindex++)
3804 p->m1 = p->m2 = 0;
3805 if (match_pattern (p, name, optabs[pindex].pattern))
3807 p->name = name;
3808 p->op = optabs[pindex].op;
3809 p->sort_num = (p->op << 20) | (p->m2 << 10) | p->m1;
3810 return true;
3813 return false;