ada: Fix infinite loop with multiple limited with clauses
[official-gcc.git] / gcc / gensupport.cc
blobdd920d673b4524447fcdba7e50995d083b067883
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 skip_spaces (&templ);
899 parse_section_layout (loc, &templ, "cons:", tconvec, true);
901 if (*templ != ']')
903 if (*templ == ';')
904 skip_spaces (&(++templ));
905 parse_section_layout (loc, &templ, "attrs:", attrvec, false);
908 if (!expect_char (&templ, ']'))
909 fatal_at (loc, "expecting `]` to end section list - section list must have "
910 "cons first, attrs second");
912 /* We will write the un-constrainified template into new_templ. */
913 std::string new_templ;
914 new_templ.append ("@");
916 /* Skip to the first proper line. */
917 skip_spaces (&templ);
918 if (*templ == 0)
919 fatal_at (loc, "'{@...}' blocks must have at least one alternative");
920 if (*templ != '\n')
921 fatal_at (loc, "unexpected character '%c' after ']'", *templ);
922 templ++;
924 alt_no = 0;
925 std::string last_line;
927 /* Process the alternatives. */
928 while (*(templ - 1) != '\0')
930 /* Skip leading whitespace. */
931 std::string buffer;
932 skip_spaces (&templ);
934 /* Check if we're at the end. */
935 if (templ[0] == '}' && templ[1] == '\0')
936 break;
938 if (expect_char (&templ, '['))
940 new_templ += '\n';
941 new_templ.append (buffer);
942 /* Parse the constraint list, then the attribute list. */
943 if (tconvec.size () > 0)
944 parse_section (&templ, tconvec.size (), alt_no, tconvec, loc,
945 "constraint");
947 if (attrvec.size () > 0)
949 if (tconvec.size () > 0 && !expect_char (&templ, ';'))
950 fatal_at (loc, "expected `;' to separate constraints "
951 "and attributes in alternative %d", alt_no);
953 parse_section (&templ, attrvec.size (), alt_no,
954 attrvec, loc, "attribute");
957 if (!expect_char (&templ, ']'))
958 fatal_at (loc, "expected end of constraint/attribute list but "
959 "missing an ending `]' in alternative %d", alt_no);
961 else if (templ[0] == '/' && templ[1] == '/')
963 templ += 2;
964 /* Glob till newline or end of string. */
965 while (*templ != '\n' || *templ != '\0')
966 templ++;
968 /* Skip any newlines or whitespaces needed. */
969 while (ISSPACE(*templ))
970 templ++;
971 continue;
973 else if (templ[0] == '/' && templ[1] == '*')
975 templ += 2;
976 /* Glob till newline or end of multiline comment. */
977 while (templ[0] != 0 && templ[0] != '*' && templ[1] != '/')
978 templ++;
980 while (templ[0] != '*' || templ[1] != '/')
982 if (templ[0] == 0)
983 fatal_at (loc, "unterminated '/*'");
984 templ++;
986 templ += 2;
988 /* Skip any newlines or whitespaces needed. */
989 while (ISSPACE(*templ))
990 templ++;
991 continue;
993 else
994 fatal_at (loc, "expected constraint/attribute list at beginning of "
995 "alternative %d but missing a starting `['", alt_no);
997 /* Skip whitespace between list and asm. */
998 skip_spaces (&templ);
1000 /* Copy asm to new template. */
1001 std::string line;
1002 while (*templ != '\n' && *templ != '\0')
1003 line += *templ++;
1005 /* Apply any pre-processing needed to the line. */
1006 preprocess_compact_syntax (loc, alt_no, line, last_line);
1007 new_templ.append (line);
1008 last_line = line;
1010 /* Normal "*..." syntax expects the closing quote to be on the final
1011 line of asm, whereas we allow the closing "}" to be on its own line.
1012 Postpone copying the '\n' until we know that there is another
1013 alternative in the list. */
1014 while (ISSPACE (*templ))
1015 templ++;
1016 ++alt_no;
1019 /* Check for any duplicate cons entries and sort based on i. */
1020 for (auto e : tconvec)
1022 unsigned idx = e.idx;
1023 if (idx >= convec.size ())
1024 convec.resize (idx + 1);
1026 if (convec[idx].idx >= 0)
1027 fatal_at (loc, "duplicate cons number found: %d", idx);
1028 convec[idx] = e;
1030 tconvec.clear ();
1032 /* Write the constraints and attributes into their proper places. */
1033 if (convec.size () > 0)
1034 add_constraints (x, loc, convec);
1036 if (attrvec.size () > 0)
1037 add_attributes (x, attrvec);
1039 /* Copy over the new un-constrainified template. */
1040 XTMPL (x, templ_index) = xstrdup (new_templ.c_str ());
1042 /* Register for later checks during iterator expansions. */
1043 compact_syntax.add (x);
1046 /* Process a top level rtx in some way, queuing as appropriate. */
1048 static void
1049 process_rtx (rtx desc, file_location loc)
1051 switch (GET_CODE (desc))
1053 case DEFINE_INSN:
1054 convert_syntax (desc, loc);
1055 queue_pattern (desc, &define_insn_tail, loc);
1056 break;
1058 case DEFINE_COND_EXEC:
1059 queue_pattern (desc, &define_cond_exec_tail, loc);
1060 break;
1062 case DEFINE_SUBST:
1063 queue_pattern (desc, &define_subst_tail, loc);
1064 break;
1066 case DEFINE_SUBST_ATTR:
1067 queue_pattern (desc, &define_subst_attr_tail, loc);
1068 break;
1070 case DEFINE_ATTR:
1071 case DEFINE_ENUM_ATTR:
1072 queue_pattern (desc, &define_attr_tail, loc);
1073 break;
1075 case DEFINE_PREDICATE:
1076 case DEFINE_SPECIAL_PREDICATE:
1077 process_define_predicate (desc, loc);
1078 /* Fall through. */
1080 case DEFINE_CONSTRAINT:
1081 case DEFINE_REGISTER_CONSTRAINT:
1082 case DEFINE_MEMORY_CONSTRAINT:
1083 case DEFINE_SPECIAL_MEMORY_CONSTRAINT:
1084 case DEFINE_RELAXED_MEMORY_CONSTRAINT:
1085 case DEFINE_ADDRESS_CONSTRAINT:
1086 queue_pattern (desc, &define_pred_tail, loc);
1087 break;
1089 case DEFINE_INSN_AND_SPLIT:
1090 case DEFINE_INSN_AND_REWRITE:
1092 const char *split_cond;
1093 rtx split;
1094 rtvec attr;
1095 int i;
1096 class queue_elem *insn_elem;
1097 class queue_elem *split_elem;
1098 int split_code = (GET_CODE (desc) == DEFINE_INSN_AND_REWRITE ? 5 : 6);
1100 /* Create a split with values from the insn_and_split. */
1101 split = rtx_alloc (DEFINE_SPLIT);
1103 i = XVECLEN (desc, 1);
1104 XVEC (split, 0) = rtvec_alloc (i);
1105 while (--i >= 0)
1107 XVECEXP (split, 0, i) = copy_rtx (XVECEXP (desc, 1, i));
1108 remove_constraints (XVECEXP (split, 0, i));
1111 /* If the split condition starts with "&&", append it to the
1112 insn condition to create the new split condition. */
1113 split_cond = XSTR (desc, 4);
1114 if (split_cond[0] == '&' && split_cond[1] == '&')
1116 rtx_reader_ptr->copy_md_ptr_loc (split_cond + 2, split_cond);
1117 split_cond = rtx_reader_ptr->join_c_conditions (XSTR (desc, 2),
1118 split_cond + 2);
1120 else if (GET_CODE (desc) == DEFINE_INSN_AND_REWRITE)
1121 error_at (loc, "the rewrite condition must start with `&&'");
1122 XSTR (split, 1) = split_cond;
1123 if (GET_CODE (desc) == DEFINE_INSN_AND_REWRITE)
1124 XVEC (split, 2) = gen_rewrite_sequence (XVEC (desc, 1));
1125 else
1126 XVEC (split, 2) = XVEC (desc, 5);
1127 XSTR (split, 3) = XSTR (desc, split_code);
1129 /* Fix up the DEFINE_INSN. */
1130 attr = XVEC (desc, split_code + 1);
1131 PUT_CODE (desc, DEFINE_INSN);
1132 XVEC (desc, 4) = attr;
1133 convert_syntax (desc, loc);
1135 /* Queue them. */
1136 insn_elem = queue_pattern (desc, &define_insn_tail, loc);
1137 split_elem = queue_pattern (split, &other_tail, loc);
1138 insn_elem->split = split_elem;
1139 break;
1142 default:
1143 queue_pattern (desc, &other_tail, loc);
1144 break;
1148 /* Return true if attribute PREDICABLE is true for ELEM, which holds
1149 a DEFINE_INSN. */
1151 static int
1152 is_predicable (class queue_elem *elem)
1154 rtvec vec = XVEC (elem->data, 4);
1155 const char *value;
1156 int i;
1158 if (! vec)
1159 return predicable_default;
1161 for (i = GET_NUM_ELEM (vec) - 1; i >= 0; --i)
1163 rtx sub = RTVEC_ELT (vec, i);
1164 switch (GET_CODE (sub))
1166 case SET_ATTR:
1167 if (strcmp (XSTR (sub, 0), "predicable") == 0)
1169 value = XSTR (sub, 1);
1170 goto found;
1172 break;
1174 case SET_ATTR_ALTERNATIVE:
1175 if (strcmp (XSTR (sub, 0), "predicable") == 0)
1177 error_at (elem->loc, "multiple alternatives for `predicable'");
1178 return 0;
1180 break;
1182 case SET:
1183 if (GET_CODE (SET_DEST (sub)) != ATTR
1184 || strcmp (XSTR (SET_DEST (sub), 0), "predicable") != 0)
1185 break;
1186 sub = SET_SRC (sub);
1187 if (GET_CODE (sub) == CONST_STRING)
1189 value = XSTR (sub, 0);
1190 goto found;
1193 /* ??? It would be possible to handle this if we really tried.
1194 It's not easy though, and I'm not going to bother until it
1195 really proves necessary. */
1196 error_at (elem->loc, "non-constant value for `predicable'");
1197 return 0;
1199 default:
1200 gcc_unreachable ();
1204 return predicable_default;
1206 found:
1207 /* Find out which value we're looking at. Multiple alternatives means at
1208 least one is predicable. */
1209 if (strchr (value, ',') != NULL)
1210 return 1;
1211 if (strcmp (value, predicable_true) == 0)
1212 return 1;
1213 if (strcmp (value, predicable_false) == 0)
1214 return 0;
1216 error_at (elem->loc, "unknown value `%s' for `predicable' attribute", value);
1217 return 0;
1220 /* Find attribute SUBST in ELEM and assign NEW_VALUE to it. */
1221 static void
1222 change_subst_attribute (class queue_elem *elem,
1223 class queue_elem *subst_elem,
1224 const char *new_value)
1226 rtvec attrs_vec = XVEC (elem->data, 4);
1227 const char *subst_name = XSTR (subst_elem->data, 0);
1228 int i;
1230 if (! attrs_vec)
1231 return;
1233 for (i = GET_NUM_ELEM (attrs_vec) - 1; i >= 0; --i)
1235 rtx cur_attr = RTVEC_ELT (attrs_vec, i);
1236 if (GET_CODE (cur_attr) != SET_ATTR)
1237 continue;
1238 if (strcmp (XSTR (cur_attr, 0), subst_name) == 0)
1240 XSTR (cur_attr, 1) = new_value;
1241 return;
1246 /* Return true if ELEM has the attribute with the name of DEFINE_SUBST
1247 represented by SUBST_ELEM and this attribute has value SUBST_TRUE.
1248 DEFINE_SUBST isn't applied to patterns without such attribute. In other
1249 words, we suppose the default value of the attribute to be 'no' since it is
1250 always generated automatically in read-rtl.cc. */
1251 static bool
1252 has_subst_attribute (class queue_elem *elem, class queue_elem *subst_elem)
1254 rtvec attrs_vec = XVEC (elem->data, 4);
1255 const char *value, *subst_name = XSTR (subst_elem->data, 0);
1256 int i;
1258 if (! attrs_vec)
1259 return false;
1261 for (i = GET_NUM_ELEM (attrs_vec) - 1; i >= 0; --i)
1263 rtx cur_attr = RTVEC_ELT (attrs_vec, i);
1264 switch (GET_CODE (cur_attr))
1266 case SET_ATTR:
1267 if (strcmp (XSTR (cur_attr, 0), subst_name) == 0)
1269 value = XSTR (cur_attr, 1);
1270 goto found;
1272 break;
1274 case SET:
1275 if (GET_CODE (SET_DEST (cur_attr)) != ATTR
1276 || strcmp (XSTR (SET_DEST (cur_attr), 0), subst_name) != 0)
1277 break;
1278 cur_attr = SET_SRC (cur_attr);
1279 if (GET_CODE (cur_attr) == CONST_STRING)
1281 value = XSTR (cur_attr, 0);
1282 goto found;
1285 /* Only (set_attr "subst" "yes/no") and
1286 (set (attr "subst" (const_string "yes/no")))
1287 are currently allowed. */
1288 error_at (elem->loc, "unsupported value for `%s'", subst_name);
1289 return false;
1291 case SET_ATTR_ALTERNATIVE:
1292 if (strcmp (XSTR (cur_attr, 0), subst_name) == 0)
1293 error_at (elem->loc,
1294 "%s: `set_attr_alternative' is unsupported by "
1295 "`define_subst'", XSTR (elem->data, 0));
1296 return false;
1299 default:
1300 gcc_unreachable ();
1304 return false;
1306 found:
1307 if (strcmp (value, subst_true) == 0)
1308 return true;
1309 if (strcmp (value, subst_false) == 0)
1310 return false;
1312 error_at (elem->loc, "unknown value `%s' for `%s' attribute",
1313 value, subst_name);
1314 return false;
1317 /* Compare RTL-template of original define_insn X to input RTL-template of
1318 define_subst PT. Return 1 if the templates match, 0 otherwise.
1319 During the comparison, the routine also fills global_array OPERAND_DATA. */
1320 static bool
1321 subst_pattern_match (rtx x, rtx pt, file_location loc)
1323 RTX_CODE code, code_pt;
1324 int i, j, len;
1325 const char *fmt, *pred_name;
1327 code = GET_CODE (x);
1328 code_pt = GET_CODE (pt);
1330 if (code_pt == MATCH_OPERAND)
1332 /* MATCH_DUP, and MATCH_OP_DUP don't have a specified mode, so we
1333 always accept them. */
1334 if (GET_MODE (pt) != VOIDmode && GET_MODE (x) != GET_MODE (pt)
1335 && (code != MATCH_DUP && code != MATCH_OP_DUP))
1336 return false; /* Modes don't match. */
1338 if (code == MATCH_OPERAND)
1340 pred_name = XSTR (pt, 1);
1341 if (pred_name[0] != 0)
1343 const struct pred_data *pred_pt = lookup_predicate (pred_name);
1344 if (!pred_pt || pred_pt != lookup_predicate (XSTR (x, 1)))
1345 return false; /* Predicates don't match. */
1349 gcc_assert (XINT (pt, 0) >= 0 && XINT (pt, 0) < MAX_OPERANDS);
1350 operand_data[XINT (pt, 0)] = x;
1351 return true;
1354 if (code_pt == MATCH_OPERATOR)
1356 int x_vecexp_pos = -1;
1358 /* Compare modes. */
1359 if (GET_MODE (pt) != VOIDmode && GET_MODE (x) != GET_MODE (pt))
1360 return false;
1362 /* In case X is also match_operator, compare predicates. */
1363 if (code == MATCH_OPERATOR)
1365 pred_name = XSTR (pt, 1);
1366 if (pred_name[0] != 0)
1368 const struct pred_data *pred_pt = lookup_predicate (pred_name);
1369 if (!pred_pt || pred_pt != lookup_predicate (XSTR (x, 1)))
1370 return false;
1374 /* Compare operands.
1375 MATCH_OPERATOR in input template could match in original template
1376 either 1) MATCH_OPERAND, 2) UNSPEC, 3) ordinary operation (like PLUS).
1377 In the first case operands are at (XVECEXP (x, 2, j)), in the second
1378 - at (XVECEXP (x, 0, j)), in the last one - (XEXP (x, j)).
1379 X_VECEXP_POS variable shows, where to look for these operands. */
1380 if (code == UNSPEC
1381 || code == UNSPEC_VOLATILE)
1382 x_vecexp_pos = 0;
1383 else if (code == MATCH_OPERATOR)
1384 x_vecexp_pos = 2;
1385 else
1386 x_vecexp_pos = -1;
1388 /* MATCH_OPERATOR or UNSPEC case. */
1389 if (x_vecexp_pos >= 0)
1391 /* Compare operands number in X and PT. */
1392 if (XVECLEN (x, x_vecexp_pos) != XVECLEN (pt, 2))
1393 return false;
1394 for (j = 0; j < XVECLEN (pt, 2); j++)
1395 if (!subst_pattern_match (XVECEXP (x, x_vecexp_pos, j),
1396 XVECEXP (pt, 2, j), loc))
1397 return false;
1400 /* Ordinary operator. */
1401 else
1403 /* Compare operands number in X and PT.
1404 We count operands differently for X and PT since we compare
1405 an operator (with operands directly in RTX) and MATCH_OPERATOR
1406 (that has a vector with operands). */
1407 if (GET_RTX_LENGTH (code) != XVECLEN (pt, 2))
1408 return false;
1409 for (j = 0; j < XVECLEN (pt, 2); j++)
1410 if (!subst_pattern_match (XEXP (x, j), XVECEXP (pt, 2, j), loc))
1411 return false;
1414 /* Store the operand to OPERAND_DATA array. */
1415 gcc_assert (XINT (pt, 0) >= 0 && XINT (pt, 0) < MAX_OPERANDS);
1416 operand_data[XINT (pt, 0)] = x;
1417 return true;
1420 if (code_pt == MATCH_PAR_DUP
1421 || code_pt == MATCH_DUP
1422 || code_pt == MATCH_OP_DUP
1423 || code_pt == MATCH_SCRATCH
1424 || code_pt == MATCH_PARALLEL)
1426 /* Currently interface for these constructions isn't defined -
1427 probably they aren't needed in input template of define_subst at all.
1428 So, for now their usage in define_subst is forbidden. */
1429 error_at (loc, "%s cannot be used in define_subst",
1430 GET_RTX_NAME (code_pt));
1433 gcc_assert (code != MATCH_PAR_DUP
1434 && code_pt != MATCH_DUP
1435 && code_pt != MATCH_OP_DUP
1436 && code_pt != MATCH_SCRATCH
1437 && code_pt != MATCH_PARALLEL
1438 && code_pt != MATCH_OPERAND
1439 && code_pt != MATCH_OPERATOR);
1440 /* If PT is none of the handled above, then we match only expressions with
1441 the same code in X. */
1442 if (code != code_pt)
1443 return false;
1445 fmt = GET_RTX_FORMAT (code_pt);
1446 len = GET_RTX_LENGTH (code_pt);
1448 for (i = 0; i < len; i++)
1450 if (fmt[i] == '0')
1451 break;
1453 switch (fmt[i])
1455 case 'r': case 'p': case 'i': case 'w': case 's':
1456 continue;
1458 case 'e': case 'u':
1459 if (!subst_pattern_match (XEXP (x, i), XEXP (pt, i), loc))
1460 return false;
1461 break;
1462 case 'E':
1464 if (XVECLEN (x, i) != XVECLEN (pt, i))
1465 return false;
1466 for (j = 0; j < XVECLEN (pt, i); j++)
1467 if (!subst_pattern_match (XVECEXP (x, i, j),
1468 XVECEXP (pt, i, j), loc))
1469 return false;
1470 break;
1472 default:
1473 gcc_unreachable ();
1477 return true;
1480 /* Examine the attribute "predicable"; discover its boolean values
1481 and its default. */
1483 static void
1484 identify_predicable_attribute (void)
1486 class queue_elem *elem;
1487 char *p_true, *p_false;
1488 const char *value;
1490 /* Look for the DEFINE_ATTR for `predicable', which must exist. */
1491 for (elem = define_attr_queue; elem ; elem = elem->next)
1492 if (strcmp (XSTR (elem->data, 0), "predicable") == 0)
1493 goto found;
1495 error_at (define_cond_exec_queue->loc,
1496 "attribute `predicable' not defined");
1497 return;
1499 found:
1500 value = XSTR (elem->data, 1);
1501 p_false = xstrdup (value);
1502 p_true = strchr (p_false, ',');
1503 if (p_true == NULL || strchr (++p_true, ',') != NULL)
1505 error_at (elem->loc, "attribute `predicable' is not a boolean");
1506 free (p_false);
1507 return;
1509 p_true[-1] = '\0';
1511 predicable_true = p_true;
1512 predicable_false = p_false;
1514 switch (GET_CODE (XEXP (elem->data, 2)))
1516 case CONST_STRING:
1517 value = XSTR (XEXP (elem->data, 2), 0);
1518 break;
1520 case CONST:
1521 error_at (elem->loc, "attribute `predicable' cannot be const");
1522 free (p_false);
1523 return;
1525 default:
1526 error_at (elem->loc,
1527 "attribute `predicable' must have a constant default");
1528 free (p_false);
1529 return;
1532 if (strcmp (value, p_true) == 0)
1533 predicable_default = 1;
1534 else if (strcmp (value, p_false) == 0)
1535 predicable_default = 0;
1536 else
1538 error_at (elem->loc, "unknown value `%s' for `predicable' attribute",
1539 value);
1540 free (p_false);
1544 /* Return the number of alternatives in constraint S. */
1546 static int
1547 n_alternatives (const char *s)
1549 int n = 1;
1551 if (s)
1552 while (*s)
1553 n += (*s++ == ',');
1555 return n;
1558 /* The routine scans rtl PATTERN, find match_operand in it and counts
1559 number of alternatives. If PATTERN contains several match_operands
1560 with different number of alternatives, error is emitted, and the
1561 routine returns 0. If all match_operands in PATTERN have the same
1562 number of alternatives, it's stored in N_ALT, and the routine returns 1.
1563 LOC is the location of PATTERN, for error reporting. */
1564 static int
1565 get_alternatives_number (rtx pattern, int *n_alt, file_location loc)
1567 const char *fmt;
1568 enum rtx_code code;
1569 int i, j, len;
1571 if (!n_alt)
1572 return 0;
1574 code = GET_CODE (pattern);
1575 switch (code)
1577 case MATCH_OPERAND:
1578 i = n_alternatives (XSTR (pattern, 2));
1579 /* n_alternatives returns 1 if constraint string is empty -
1580 here we fix it up. */
1581 if (!*(XSTR (pattern, 2)))
1582 i = 0;
1583 if (*n_alt <= 0)
1584 *n_alt = i;
1586 else if (i && i != *n_alt)
1588 error_at (loc, "wrong number of alternatives in operand %d",
1589 XINT (pattern, 0));
1590 return 0;
1593 default:
1594 break;
1597 fmt = GET_RTX_FORMAT (code);
1598 len = GET_RTX_LENGTH (code);
1599 for (i = 0; i < len; i++)
1601 switch (fmt[i])
1603 case 'e': case 'u':
1604 if (!get_alternatives_number (XEXP (pattern, i), n_alt, loc))
1605 return 0;
1606 break;
1608 case 'V':
1609 if (XVEC (pattern, i) == NULL)
1610 break;
1611 /* FALLTHRU */
1613 case 'E':
1614 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
1615 if (!get_alternatives_number (XVECEXP (pattern, i, j), n_alt, loc))
1616 return 0;
1617 break;
1619 case 'r': case 'p': case 'i': case 'w':
1620 case '0': case 's': case 'S': case 'T':
1621 break;
1623 default:
1624 gcc_unreachable ();
1627 return 1;
1630 /* Determine how many alternatives there are in INSN, and how many
1631 operands. */
1633 static void
1634 collect_insn_data (rtx pattern, int *palt, int *pmax)
1636 const char *fmt;
1637 enum rtx_code code;
1638 int i, j, len;
1640 code = GET_CODE (pattern);
1641 switch (code)
1643 case MATCH_OPERAND:
1644 case MATCH_SCRATCH:
1645 i = n_alternatives (XSTR (pattern, code == MATCH_SCRATCH ? 1 : 2));
1646 *palt = (i > *palt ? i : *palt);
1647 /* Fall through. */
1649 case MATCH_OPERATOR:
1650 case MATCH_PARALLEL:
1651 i = XINT (pattern, 0);
1652 if (i > *pmax)
1653 *pmax = i;
1654 break;
1656 default:
1657 break;
1660 fmt = GET_RTX_FORMAT (code);
1661 len = GET_RTX_LENGTH (code);
1662 for (i = 0; i < len; i++)
1664 switch (fmt[i])
1666 case 'e': case 'u':
1667 collect_insn_data (XEXP (pattern, i), palt, pmax);
1668 break;
1670 case 'V':
1671 if (XVEC (pattern, i) == NULL)
1672 break;
1673 /* Fall through. */
1674 case 'E':
1675 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
1676 collect_insn_data (XVECEXP (pattern, i, j), palt, pmax);
1677 break;
1679 case 'r': case 'p': case 'i': case 'w':
1680 case '0': case 's': case 'S': case 'T':
1681 break;
1683 default:
1684 gcc_unreachable ();
1689 static rtx
1690 alter_predicate_for_insn (rtx pattern, int alt, int max_op,
1691 file_location loc)
1693 const char *fmt;
1694 enum rtx_code code;
1695 int i, j, len;
1697 code = GET_CODE (pattern);
1698 switch (code)
1700 case MATCH_OPERAND:
1702 const char *c = XSTR (pattern, 2);
1704 if (n_alternatives (c) != 1)
1706 error_at (loc, "too many alternatives for operand %d",
1707 XINT (pattern, 0));
1708 return NULL;
1711 /* Replicate C as needed to fill out ALT alternatives. */
1712 if (c && *c && alt > 1)
1714 size_t c_len = strlen (c);
1715 size_t len = alt * (c_len + 1);
1716 char *new_c = XNEWVEC (char, len);
1718 memcpy (new_c, c, c_len);
1719 for (i = 1; i < alt; ++i)
1721 new_c[i * (c_len + 1) - 1] = ',';
1722 memcpy (&new_c[i * (c_len + 1)], c, c_len);
1724 new_c[len - 1] = '\0';
1725 XSTR (pattern, 2) = new_c;
1728 /* Fall through. */
1730 case MATCH_OPERATOR:
1731 case MATCH_SCRATCH:
1732 case MATCH_PARALLEL:
1733 case MATCH_DUP:
1734 XINT (pattern, 0) += max_op;
1735 break;
1737 default:
1738 break;
1741 fmt = GET_RTX_FORMAT (code);
1742 len = GET_RTX_LENGTH (code);
1743 for (i = 0; i < len; i++)
1745 rtx r;
1747 switch (fmt[i])
1749 case 'e': case 'u':
1750 r = alter_predicate_for_insn (XEXP (pattern, i), alt, max_op, loc);
1751 if (r == NULL)
1752 return r;
1753 break;
1755 case 'E':
1756 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
1758 r = alter_predicate_for_insn (XVECEXP (pattern, i, j),
1759 alt, max_op, loc);
1760 if (r == NULL)
1761 return r;
1763 break;
1765 case 'r': case 'p': case 'i': case 'w': case '0': case 's':
1766 break;
1768 default:
1769 gcc_unreachable ();
1773 return pattern;
1776 /* Duplicate constraints in PATTERN. If pattern is from original
1777 rtl-template, we need to duplicate each alternative - for that we
1778 need to use duplicate_each_alternative () as a functor ALTER.
1779 If pattern is from output-pattern of define_subst, we need to
1780 duplicate constraints in another way - with duplicate_alternatives ().
1781 N_DUP is multiplication factor. */
1782 static rtx
1783 alter_constraints (rtx pattern, int n_dup, constraints_handler_t alter)
1785 const char *fmt;
1786 enum rtx_code code;
1787 int i, j, len;
1789 code = GET_CODE (pattern);
1790 switch (code)
1792 case MATCH_OPERAND:
1793 XSTR (pattern, 2) = alter (XSTR (pattern, 2), n_dup);
1794 break;
1795 case MATCH_SCRATCH:
1796 XSTR (pattern, 1) = alter (XSTR (pattern, 1), n_dup);
1797 break;
1799 default:
1800 break;
1803 fmt = GET_RTX_FORMAT (code);
1804 len = GET_RTX_LENGTH (code);
1805 for (i = 0; i < len; i++)
1807 rtx r;
1809 switch (fmt[i])
1811 case 'e': case 'u':
1812 r = alter_constraints (XEXP (pattern, i), n_dup, alter);
1813 if (r == NULL)
1814 return r;
1815 break;
1817 case 'E':
1818 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
1820 r = alter_constraints (XVECEXP (pattern, i, j), n_dup, alter);
1821 if (r == NULL)
1822 return r;
1824 break;
1826 case 'r': case 'p': case 'i': case 'w': case '0': case 's':
1827 break;
1829 default:
1830 break;
1834 return pattern;
1837 static const char *
1838 alter_test_for_insn (class queue_elem *ce_elem,
1839 class queue_elem *insn_elem)
1841 return rtx_reader_ptr->join_c_conditions (XSTR (ce_elem->data, 1),
1842 XSTR (insn_elem->data, 2));
1845 /* Modify VAL, which is an attribute expression for the "enabled" attribute,
1846 to take "ce_enabled" into account. Return the new expression. */
1847 static rtx
1848 modify_attr_enabled_ce (rtx val)
1850 rtx eq_attr, str;
1851 rtx ite;
1852 eq_attr = rtx_alloc (EQ_ATTR);
1853 ite = rtx_alloc (IF_THEN_ELSE);
1854 str = rtx_alloc (CONST_STRING);
1856 XSTR (eq_attr, 0) = "ce_enabled";
1857 XSTR (eq_attr, 1) = "yes";
1858 XSTR (str, 0) = "no";
1859 XEXP (ite, 0) = eq_attr;
1860 XEXP (ite, 1) = val;
1861 XEXP (ite, 2) = str;
1863 return ite;
1866 /* Alter the attribute vector of INSN, which is a COND_EXEC variant created
1867 from a define_insn pattern. We must modify the "predicable" attribute
1868 to be named "ce_enabled", and also change any "enabled" attribute that's
1869 present so that it takes ce_enabled into account.
1870 We rely on the fact that INSN was created with copy_rtx, and modify data
1871 in-place. */
1873 static void
1874 alter_attrs_for_insn (rtx insn)
1876 static bool global_changes_made = false;
1877 rtvec vec = XVEC (insn, 4);
1878 rtvec new_vec;
1879 rtx val, set;
1880 int num_elem;
1881 int predicable_idx = -1;
1882 int enabled_idx = -1;
1883 int i;
1885 if (! vec)
1886 return;
1888 num_elem = GET_NUM_ELEM (vec);
1889 for (i = num_elem - 1; i >= 0; --i)
1891 rtx sub = RTVEC_ELT (vec, i);
1892 switch (GET_CODE (sub))
1894 case SET_ATTR:
1895 if (strcmp (XSTR (sub, 0), "predicable") == 0)
1897 predicable_idx = i;
1898 XSTR (sub, 0) = "ce_enabled";
1900 else if (strcmp (XSTR (sub, 0), "enabled") == 0)
1902 enabled_idx = i;
1903 XSTR (sub, 0) = "nonce_enabled";
1905 break;
1907 case SET_ATTR_ALTERNATIVE:
1908 if (strcmp (XSTR (sub, 0), "predicable") == 0)
1909 /* We already give an error elsewhere. */
1910 return;
1911 else if (strcmp (XSTR (sub, 0), "enabled") == 0)
1913 enabled_idx = i;
1914 XSTR (sub, 0) = "nonce_enabled";
1916 break;
1918 case SET:
1919 if (GET_CODE (SET_DEST (sub)) != ATTR)
1920 break;
1921 if (strcmp (XSTR (SET_DEST (sub), 0), "predicable") == 0)
1923 sub = SET_SRC (sub);
1924 if (GET_CODE (sub) == CONST_STRING)
1926 predicable_idx = i;
1927 XSTR (sub, 0) = "ce_enabled";
1929 else
1930 /* We already give an error elsewhere. */
1931 return;
1932 break;
1934 if (strcmp (XSTR (SET_DEST (sub), 0), "enabled") == 0)
1936 enabled_idx = i;
1937 XSTR (SET_DEST (sub), 0) = "nonce_enabled";
1939 break;
1941 default:
1942 gcc_unreachable ();
1945 if (predicable_idx == -1)
1946 return;
1948 if (!global_changes_made)
1950 class queue_elem *elem;
1952 global_changes_made = true;
1953 add_define_attr ("ce_enabled");
1954 add_define_attr ("nonce_enabled");
1956 for (elem = define_attr_queue; elem ; elem = elem->next)
1957 if (strcmp (XSTR (elem->data, 0), "enabled") == 0)
1959 XEXP (elem->data, 2)
1960 = modify_attr_enabled_ce (XEXP (elem->data, 2));
1963 if (enabled_idx == -1)
1964 return;
1966 new_vec = rtvec_alloc (num_elem + 1);
1967 for (i = 0; i < num_elem; i++)
1968 RTVEC_ELT (new_vec, i) = RTVEC_ELT (vec, i);
1969 val = rtx_alloc (IF_THEN_ELSE);
1970 XEXP (val, 0) = rtx_alloc (EQ_ATTR);
1971 XEXP (val, 1) = rtx_alloc (CONST_STRING);
1972 XEXP (val, 2) = rtx_alloc (CONST_STRING);
1973 XSTR (XEXP (val, 0), 0) = "nonce_enabled";
1974 XSTR (XEXP (val, 0), 1) = "yes";
1975 XSTR (XEXP (val, 1), 0) = "yes";
1976 XSTR (XEXP (val, 2), 0) = "no";
1977 set = rtx_alloc (SET);
1978 SET_DEST (set) = rtx_alloc (ATTR);
1979 XSTR (SET_DEST (set), 0) = "enabled";
1980 SET_SRC (set) = modify_attr_enabled_ce (val);
1981 RTVEC_ELT (new_vec, i) = set;
1982 XVEC (insn, 4) = new_vec;
1985 /* As number of constraints is changed after define_subst, we need to
1986 process attributes as well - we need to duplicate them the same way
1987 that we duplicated constraints in original pattern
1988 ELEM is a queue element, containing our rtl-template,
1989 N_DUP - multiplication factor. */
1990 static void
1991 alter_attrs_for_subst_insn (class queue_elem * elem, int n_dup)
1993 rtvec vec = XVEC (elem->data, 4);
1994 int num_elem;
1995 int i;
1997 if (n_dup < 2 || ! vec)
1998 return;
2000 num_elem = GET_NUM_ELEM (vec);
2001 for (i = num_elem - 1; i >= 0; --i)
2003 rtx sub = RTVEC_ELT (vec, i);
2004 switch (GET_CODE (sub))
2006 case SET_ATTR:
2007 if (strchr (XSTR (sub, 1), ',') != NULL)
2008 XSTR (sub, 1) = duplicate_alternatives (XSTR (sub, 1), n_dup);
2009 break;
2011 case SET_ATTR_ALTERNATIVE:
2012 case SET:
2013 error_at (elem->loc,
2014 "%s: `define_subst' does not support attributes "
2015 "assigned by `set' and `set_attr_alternative'",
2016 XSTR (elem->data, 0));
2017 return;
2019 default:
2020 gcc_unreachable ();
2025 /* Adjust all of the operand numbers in SRC to match the shift they'll
2026 get from an operand displacement of DISP. Return a pointer after the
2027 adjusted string. */
2029 static char *
2030 shift_output_template (char *dest, const char *src, int disp)
2032 while (*src)
2034 char c = *src++;
2035 *dest++ = c;
2036 if (c == '%')
2038 c = *src++;
2039 if (ISDIGIT ((unsigned char) c))
2040 c += disp;
2041 else if (ISALPHA (c))
2043 *dest++ = c;
2044 c = *src++ + disp;
2046 *dest++ = c;
2050 return dest;
2053 static const char *
2054 alter_output_for_insn (class queue_elem *ce_elem,
2055 class queue_elem *insn_elem,
2056 int alt, int max_op)
2058 const char *ce_out, *insn_out;
2059 char *result, *p;
2060 size_t len, ce_len, insn_len;
2062 /* ??? Could coordinate with genoutput to not duplicate code here. */
2064 ce_out = XSTR (ce_elem->data, 2);
2065 insn_out = XTMPL (insn_elem->data, 3);
2066 if (!ce_out || *ce_out == '\0')
2067 return insn_out;
2069 ce_len = strlen (ce_out);
2070 insn_len = strlen (insn_out);
2072 if (*insn_out == '*')
2073 /* You must take care of the predicate yourself. */
2074 return insn_out;
2076 if (*insn_out == '@')
2078 len = (ce_len + 1) * alt + insn_len + 1;
2079 p = result = XNEWVEC (char, len);
2084 *p++ = *insn_out++;
2085 while (ISSPACE ((unsigned char) *insn_out));
2087 if (*insn_out != '#')
2089 p = shift_output_template (p, ce_out, max_op);
2090 *p++ = ' ';
2094 *p++ = *insn_out++;
2095 while (*insn_out && *insn_out != '\n');
2097 while (*insn_out);
2098 *p = '\0';
2100 else
2102 len = ce_len + 1 + insn_len + 1;
2103 result = XNEWVEC (char, len);
2105 p = shift_output_template (result, ce_out, max_op);
2106 *p++ = ' ';
2107 memcpy (p, insn_out, insn_len + 1);
2110 return result;
2113 /* From string STR "a,b,c" produce "a,b,c,a,b,c,a,b,c", i.e. original
2114 string, duplicated N_DUP times. */
2116 static const char *
2117 duplicate_alternatives (const char * str, int n_dup)
2119 int i, len, new_len;
2120 char *result, *sp;
2121 const char *cp;
2123 if (n_dup < 2)
2124 return str;
2126 while (ISSPACE (*str))
2127 str++;
2129 if (*str == '\0')
2130 return str;
2132 cp = str;
2133 len = strlen (str);
2134 new_len = (len + 1) * n_dup;
2136 sp = result = XNEWVEC (char, new_len);
2138 /* Global modifier characters mustn't be duplicated: skip if found. */
2139 if (*cp == '=' || *cp == '+' || *cp == '%')
2141 *sp++ = *cp++;
2142 len--;
2145 /* Copy original constraints N_DUP times. */
2146 for (i = 0; i < n_dup; i++, sp += len+1)
2148 memcpy (sp, cp, len);
2149 *(sp+len) = (i == n_dup - 1) ? '\0' : ',';
2152 return result;
2155 /* From string STR "a,b,c" produce "a,a,a,b,b,b,c,c,c", i.e. string where
2156 each alternative from the original string is duplicated N_DUP times. */
2157 static const char *
2158 duplicate_each_alternative (const char * str, int n_dup)
2160 int i, len, new_len;
2161 char *result, *sp, *ep, *cp;
2163 if (n_dup < 2)
2164 return str;
2166 while (ISSPACE (*str))
2167 str++;
2169 if (*str == '\0')
2170 return str;
2172 cp = xstrdup (str);
2174 new_len = (strlen (cp) + 1) * n_dup;
2176 sp = result = XNEWVEC (char, new_len);
2178 /* Global modifier characters mustn't be duplicated: skip if found. */
2179 if (*cp == '=' || *cp == '+' || *cp == '%')
2180 *sp++ = *cp++;
2184 if ((ep = strchr (cp, ',')) != NULL)
2185 *ep++ = '\0';
2186 len = strlen (cp);
2188 /* Copy a constraint N_DUP times. */
2189 for (i = 0; i < n_dup; i++, sp += len + 1)
2191 memcpy (sp, cp, len);
2192 *(sp+len) = (ep == NULL && i == n_dup - 1) ? '\0' : ',';
2195 cp = ep;
2197 while (cp != NULL);
2199 return result;
2202 /* Alter the output of INSN whose pattern was modified by
2203 DEFINE_SUBST. We must replicate output strings according
2204 to the new number of alternatives ALT in substituted pattern.
2205 If ALT equals 1, output has one alternative or defined by C
2206 code, then output is returned without any changes. */
2208 static const char *
2209 alter_output_for_subst_insn (rtx insn, int alt)
2211 const char *insn_out, *old_out;
2212 char *new_out, *cp;
2213 size_t old_len, new_len;
2214 int j;
2216 insn_out = XTMPL (insn, 3);
2218 if (alt < 2 || *insn_out != '@')
2219 return insn_out;
2221 old_out = insn_out + 1;
2222 while (ISSPACE (*old_out))
2223 old_out++;
2224 old_len = strlen (old_out);
2226 new_len = alt * (old_len + 1) + 1;
2228 new_out = XNEWVEC (char, new_len);
2229 new_out[0] = '@';
2231 for (j = 0, cp = new_out + 1; j < alt; j++, cp += old_len + 1)
2233 memcpy (cp, old_out, old_len);
2234 cp[old_len] = (j == alt - 1) ? '\0' : '\n';
2237 return new_out;
2240 /* Replicate insns as appropriate for the given DEFINE_COND_EXEC. */
2242 static void
2243 process_one_cond_exec (class queue_elem *ce_elem)
2245 class queue_elem *insn_elem;
2246 for (insn_elem = define_insn_queue; insn_elem ; insn_elem = insn_elem->next)
2248 int alternatives, max_operand;
2249 rtx pred, insn, pattern, split;
2250 char *new_name;
2251 int i;
2253 if (! is_predicable (insn_elem))
2254 continue;
2256 alternatives = 1;
2257 max_operand = -1;
2258 collect_insn_data (insn_elem->data, &alternatives, &max_operand);
2259 max_operand += 1;
2261 if (XVECLEN (ce_elem->data, 0) != 1)
2263 error_at (ce_elem->loc, "too many patterns in predicate");
2264 return;
2267 pred = copy_rtx (XVECEXP (ce_elem->data, 0, 0));
2268 pred = alter_predicate_for_insn (pred, alternatives, max_operand,
2269 ce_elem->loc);
2270 if (pred == NULL)
2271 return;
2273 /* Construct a new pattern for the new insn. */
2274 insn = copy_rtx (insn_elem->data);
2275 new_name = XNEWVAR (char, strlen XSTR (insn_elem->data, 0) + 4);
2276 sprintf (new_name, "*p %s", XSTR (insn_elem->data, 0));
2277 XSTR (insn, 0) = new_name;
2278 pattern = rtx_alloc (COND_EXEC);
2279 XEXP (pattern, 0) = pred;
2280 XEXP (pattern, 1) = add_implicit_parallel (XVEC (insn, 1));
2281 XVEC (insn, 1) = rtvec_alloc (1);
2282 XVECEXP (insn, 1, 0) = pattern;
2284 if (XVEC (ce_elem->data, 3) != NULL)
2286 rtvec attributes = rtvec_alloc (XVECLEN (insn, 4)
2287 + XVECLEN (ce_elem->data, 3));
2288 int i = 0;
2289 int j = 0;
2290 for (i = 0; i < XVECLEN (insn, 4); i++)
2291 RTVEC_ELT (attributes, i) = XVECEXP (insn, 4, i);
2293 for (j = 0; j < XVECLEN (ce_elem->data, 3); j++, i++)
2294 RTVEC_ELT (attributes, i) = XVECEXP (ce_elem->data, 3, j);
2296 XVEC (insn, 4) = attributes;
2299 XSTR (insn, 2) = alter_test_for_insn (ce_elem, insn_elem);
2300 XTMPL (insn, 3) = alter_output_for_insn (ce_elem, insn_elem,
2301 alternatives, max_operand);
2302 alter_attrs_for_insn (insn);
2304 /* Put the new pattern on the `other' list so that it
2305 (a) is not reprocessed by other define_cond_exec patterns
2306 (b) appears after all normal define_insn patterns.
2308 ??? B is debatable. If one has normal insns that match
2309 cond_exec patterns, they will be preferred over these
2310 generated patterns. Whether this matters in practice, or if
2311 it's a good thing, or whether we should thread these new
2312 patterns into the define_insn chain just after their generator
2313 is something we'll have to experiment with. */
2315 queue_pattern (insn, &other_tail, insn_elem->loc);
2317 if (!insn_elem->split)
2318 continue;
2320 /* If the original insn came from a define_insn_and_split,
2321 generate a new split to handle the predicated insn. */
2322 split = copy_rtx (insn_elem->split->data);
2323 /* Predicate the pattern matched by the split. */
2324 pattern = rtx_alloc (COND_EXEC);
2325 XEXP (pattern, 0) = pred;
2326 XEXP (pattern, 1) = add_implicit_parallel (XVEC (split, 0));
2327 XVEC (split, 0) = rtvec_alloc (1);
2328 XVECEXP (split, 0, 0) = pattern;
2330 /* Predicate all of the insns generated by the split. */
2331 for (i = 0; i < XVECLEN (split, 2); i++)
2333 pattern = rtx_alloc (COND_EXEC);
2334 XEXP (pattern, 0) = pred;
2335 XEXP (pattern, 1) = XVECEXP (split, 2, i);
2336 XVECEXP (split, 2, i) = pattern;
2338 /* Add the new split to the queue. */
2339 queue_pattern (split, &other_tail, insn_elem->split->loc);
2343 /* Try to apply define_substs to the given ELEM.
2344 Only define_substs, specified via attributes would be applied.
2345 If attribute, requiring define_subst, is set, but no define_subst
2346 was applied, ELEM would be deleted. */
2348 static void
2349 process_substs_on_one_elem (class queue_elem *elem,
2350 class queue_elem *queue)
2352 class queue_elem *subst_elem;
2353 int i, j, patterns_match;
2355 for (subst_elem = define_subst_queue;
2356 subst_elem; subst_elem = subst_elem->next)
2358 int alternatives, alternatives_subst;
2359 rtx subst_pattern;
2360 rtvec subst_pattern_vec;
2362 if (!has_subst_attribute (elem, subst_elem))
2363 continue;
2365 /* Compare original rtl-pattern from define_insn with input
2366 pattern from define_subst.
2367 Also, check if numbers of alternatives are the same in all
2368 match_operands. */
2369 if (XVECLEN (elem->data, 1) != XVECLEN (subst_elem->data, 1))
2370 continue;
2371 patterns_match = 1;
2372 alternatives = -1;
2373 alternatives_subst = -1;
2374 for (j = 0; j < XVECLEN (elem->data, 1); j++)
2376 if (!subst_pattern_match (XVECEXP (elem->data, 1, j),
2377 XVECEXP (subst_elem->data, 1, j),
2378 subst_elem->loc))
2380 patterns_match = 0;
2381 break;
2384 if (!get_alternatives_number (XVECEXP (elem->data, 1, j),
2385 &alternatives, subst_elem->loc))
2387 patterns_match = 0;
2388 break;
2392 /* Check if numbers of alternatives are the same in all
2393 match_operands in output template of define_subst. */
2394 for (j = 0; j < XVECLEN (subst_elem->data, 3); j++)
2396 if (!get_alternatives_number (XVECEXP (subst_elem->data, 3, j),
2397 &alternatives_subst,
2398 subst_elem->loc))
2400 patterns_match = 0;
2401 break;
2405 if (!patterns_match)
2406 continue;
2408 /* Clear array in which we save occupied indexes of operands. */
2409 memset (used_operands_numbers, 0, sizeof (used_operands_numbers));
2411 /* Create a pattern, based on the output one from define_subst. */
2412 subst_pattern_vec = rtvec_alloc (XVECLEN (subst_elem->data, 3));
2413 for (j = 0; j < XVECLEN (subst_elem->data, 3); j++)
2415 subst_pattern = copy_rtx (XVECEXP (subst_elem->data, 3, j));
2417 /* Duplicate constraints in substitute-pattern. */
2418 subst_pattern = alter_constraints (subst_pattern, alternatives,
2419 duplicate_each_alternative);
2421 subst_pattern = adjust_operands_numbers (subst_pattern);
2423 /* Substitute match_dup and match_op_dup in the new pattern and
2424 duplicate constraints. */
2425 subst_pattern = subst_dup (subst_pattern, alternatives,
2426 alternatives_subst);
2428 replace_duplicating_operands_in_pattern (subst_pattern);
2430 /* We don't need any constraints in DEFINE_EXPAND. */
2431 if (GET_CODE (elem->data) == DEFINE_EXPAND)
2432 remove_constraints (subst_pattern);
2434 RTVEC_ELT (subst_pattern_vec, j) = subst_pattern;
2436 XVEC (elem->data, 1) = subst_pattern_vec;
2438 for (i = 0; i < MAX_OPERANDS; i++)
2439 match_operand_entries_in_pattern[i] = NULL;
2441 if (GET_CODE (elem->data) == DEFINE_INSN)
2443 XTMPL (elem->data, 3) =
2444 alter_output_for_subst_insn (elem->data, alternatives_subst);
2445 alter_attrs_for_subst_insn (elem, alternatives_subst);
2448 /* Recalculate condition, joining conditions from original and
2449 DEFINE_SUBST input patterns. */
2450 XSTR (elem->data, 2)
2451 = rtx_reader_ptr->join_c_conditions (XSTR (subst_elem->data, 2),
2452 XSTR (elem->data, 2));
2453 /* Mark that subst was applied by changing attribute from "yes"
2454 to "no". */
2455 change_subst_attribute (elem, subst_elem, subst_false);
2458 /* If ELEM contains a subst attribute with value "yes", then we
2459 expected that a subst would be applied, but it wasn't - so,
2460 we need to remove that elementto avoid duplicating. */
2461 for (subst_elem = define_subst_queue;
2462 subst_elem; subst_elem = subst_elem->next)
2464 if (has_subst_attribute (elem, subst_elem))
2466 remove_from_queue (elem, &queue);
2467 return;
2472 /* This is a subroutine of mark_operands_used_in_match_dup.
2473 This routine is marks all MATCH_OPERANDs inside PATTERN as occupied. */
2474 static void
2475 mark_operands_from_match_dup (rtx pattern)
2477 const char *fmt;
2478 int i, j, len, opno;
2480 if (GET_CODE (pattern) == MATCH_OPERAND
2481 || GET_CODE (pattern) == MATCH_OPERATOR
2482 || GET_CODE (pattern) == MATCH_PARALLEL)
2484 opno = XINT (pattern, 0);
2485 gcc_assert (opno >= 0 && opno < MAX_OPERANDS);
2486 used_operands_numbers [opno] = 1;
2488 fmt = GET_RTX_FORMAT (GET_CODE (pattern));
2489 len = GET_RTX_LENGTH (GET_CODE (pattern));
2490 for (i = 0; i < len; i++)
2492 switch (fmt[i])
2494 case 'e': case 'u':
2495 mark_operands_from_match_dup (XEXP (pattern, i));
2496 break;
2497 case 'E':
2498 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
2499 mark_operands_from_match_dup (XVECEXP (pattern, i, j));
2500 break;
2505 /* This is a subroutine of adjust_operands_numbers.
2506 It goes through all expressions in PATTERN and when MATCH_DUP is
2507 met, all MATCH_OPERANDs inside it is marked as occupied. The
2508 process of marking is done by routin mark_operands_from_match_dup. */
2509 static void
2510 mark_operands_used_in_match_dup (rtx pattern)
2512 const char *fmt;
2513 int i, j, len, opno;
2515 if (GET_CODE (pattern) == MATCH_DUP)
2517 opno = XINT (pattern, 0);
2518 gcc_assert (opno >= 0 && opno < MAX_OPERANDS);
2519 mark_operands_from_match_dup (operand_data[opno]);
2520 return;
2522 fmt = GET_RTX_FORMAT (GET_CODE (pattern));
2523 len = GET_RTX_LENGTH (GET_CODE (pattern));
2524 for (i = 0; i < len; i++)
2526 switch (fmt[i])
2528 case 'e': case 'u':
2529 mark_operands_used_in_match_dup (XEXP (pattern, i));
2530 break;
2531 case 'E':
2532 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
2533 mark_operands_used_in_match_dup (XVECEXP (pattern, i, j));
2534 break;
2539 /* This is subroutine of renumerate_operands_in_pattern.
2540 It finds first not-occupied operand-index. */
2541 static int
2542 find_first_unused_number_of_operand ()
2544 int i;
2545 for (i = 0; i < MAX_OPERANDS; i++)
2546 if (!used_operands_numbers[i])
2547 return i;
2548 return MAX_OPERANDS;
2551 /* This is subroutine of adjust_operands_numbers.
2552 It visits all expressions in PATTERN and assigns not-occupied
2553 operand indexes to MATCH_OPERANDs and MATCH_OPERATORs of this
2554 PATTERN. */
2555 static void
2556 renumerate_operands_in_pattern (rtx pattern)
2558 const char *fmt;
2559 enum rtx_code code;
2560 int i, j, len, new_opno;
2561 code = GET_CODE (pattern);
2563 if (code == MATCH_OPERAND
2564 || code == MATCH_OPERATOR)
2566 new_opno = find_first_unused_number_of_operand ();
2567 gcc_assert (new_opno >= 0 && new_opno < MAX_OPERANDS);
2568 XINT (pattern, 0) = new_opno;
2569 used_operands_numbers [new_opno] = 1;
2572 fmt = GET_RTX_FORMAT (GET_CODE (pattern));
2573 len = GET_RTX_LENGTH (GET_CODE (pattern));
2574 for (i = 0; i < len; i++)
2576 switch (fmt[i])
2578 case 'e': case 'u':
2579 renumerate_operands_in_pattern (XEXP (pattern, i));
2580 break;
2581 case 'E':
2582 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
2583 renumerate_operands_in_pattern (XVECEXP (pattern, i, j));
2584 break;
2589 /* If output pattern of define_subst contains MATCH_DUP, then this
2590 expression would be replaced with the pattern, matched with
2591 MATCH_OPERAND from input pattern. This pattern could contain any
2592 number of MATCH_OPERANDs, MATCH_OPERATORs etc., so it's possible
2593 that a MATCH_OPERAND from output_pattern (if any) would have the
2594 same number, as MATCH_OPERAND from copied pattern. To avoid such
2595 indexes overlapping, we assign new indexes to MATCH_OPERANDs,
2596 laying in the output pattern outside of MATCH_DUPs. */
2597 static rtx
2598 adjust_operands_numbers (rtx pattern)
2600 mark_operands_used_in_match_dup (pattern);
2602 renumerate_operands_in_pattern (pattern);
2604 return pattern;
2607 /* Generate RTL expression
2608 (match_dup OPNO)
2610 static rtx
2611 generate_match_dup (int opno)
2613 rtx return_rtx = rtx_alloc (MATCH_DUP);
2614 PUT_CODE (return_rtx, MATCH_DUP);
2615 XINT (return_rtx, 0) = opno;
2616 return return_rtx;
2619 /* This routine checks all match_operands in PATTERN and if some of
2620 have the same index, it replaces all of them except the first one to
2621 match_dup.
2622 Usually, match_operands with the same indexes are forbidden, but
2623 after define_subst copy an RTL-expression from original template,
2624 indexes of existed and just-copied match_operands could coincide.
2625 To fix it, we replace one of them with match_dup. */
2626 static rtx
2627 replace_duplicating_operands_in_pattern (rtx pattern)
2629 const char *fmt;
2630 int i, j, len, opno;
2631 rtx mdup;
2633 if (GET_CODE (pattern) == MATCH_OPERAND)
2635 opno = XINT (pattern, 0);
2636 gcc_assert (opno >= 0 && opno < MAX_OPERANDS);
2637 if (match_operand_entries_in_pattern[opno] == NULL)
2639 match_operand_entries_in_pattern[opno] = pattern;
2640 return NULL;
2642 else
2644 /* Compare predicates before replacing with match_dup. */
2645 if (strcmp (XSTR (pattern, 1),
2646 XSTR (match_operand_entries_in_pattern[opno], 1)))
2648 error ("duplicated match_operands with different predicates were"
2649 " found.");
2650 return NULL;
2652 return generate_match_dup (opno);
2655 fmt = GET_RTX_FORMAT (GET_CODE (pattern));
2656 len = GET_RTX_LENGTH (GET_CODE (pattern));
2657 for (i = 0; i < len; i++)
2659 switch (fmt[i])
2661 case 'e': case 'u':
2662 mdup = replace_duplicating_operands_in_pattern (XEXP (pattern, i));
2663 if (mdup)
2664 XEXP (pattern, i) = mdup;
2665 break;
2666 case 'E':
2667 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
2669 mdup =
2670 replace_duplicating_operands_in_pattern (XVECEXP
2671 (pattern, i, j));
2672 if (mdup)
2673 XVECEXP (pattern, i, j) = mdup;
2675 break;
2678 return NULL;
2681 /* The routine modifies given input PATTERN of define_subst, replacing
2682 MATCH_DUP and MATCH_OP_DUP with operands from define_insn original
2683 pattern, whose operands are stored in OPERAND_DATA array.
2684 It also duplicates constraints in operands - constraints from
2685 define_insn operands are duplicated N_SUBST_ALT times, constraints
2686 from define_subst operands are duplicated N_ALT times.
2687 After the duplication, returned output rtl-pattern contains every
2688 combination of input constraints Vs constraints from define_subst
2689 output. */
2690 static rtx
2691 subst_dup (rtx pattern, int n_alt, int n_subst_alt)
2693 const char *fmt;
2694 enum rtx_code code;
2695 int i, j, len, opno;
2697 code = GET_CODE (pattern);
2698 switch (code)
2700 case MATCH_DUP:
2701 case MATCH_OP_DUP:
2702 opno = XINT (pattern, 0);
2704 gcc_assert (opno >= 0 && opno < MAX_OPERANDS);
2706 if (operand_data[opno])
2708 pattern = copy_rtx (operand_data[opno]);
2710 /* Duplicate constraints. */
2711 pattern = alter_constraints (pattern, n_subst_alt,
2712 duplicate_alternatives);
2714 break;
2716 default:
2717 break;
2720 fmt = GET_RTX_FORMAT (GET_CODE (pattern));
2721 len = GET_RTX_LENGTH (GET_CODE (pattern));
2722 for (i = 0; i < len; i++)
2724 switch (fmt[i])
2726 case 'e': case 'u':
2727 if (code != MATCH_DUP && code != MATCH_OP_DUP)
2728 XEXP (pattern, i) = subst_dup (XEXP (pattern, i),
2729 n_alt, n_subst_alt);
2730 break;
2731 case 'V':
2732 if (XVEC (pattern, i) == NULL)
2733 break;
2734 /* FALLTHRU */
2735 case 'E':
2736 if (code != MATCH_DUP && code != MATCH_OP_DUP)
2737 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j)
2738 XVECEXP (pattern, i, j) = subst_dup (XVECEXP (pattern, i, j),
2739 n_alt, n_subst_alt);
2740 break;
2742 case 'r': case 'p': case 'i': case 'w':
2743 case '0': case 's': case 'S': case 'T':
2744 break;
2746 default:
2747 gcc_unreachable ();
2750 return pattern;
2753 /* If we have any DEFINE_COND_EXEC patterns, expand the DEFINE_INSN
2754 patterns appropriately. */
2756 static void
2757 process_define_cond_exec (void)
2759 class queue_elem *elem;
2761 identify_predicable_attribute ();
2762 if (have_error)
2763 return;
2765 for (elem = define_cond_exec_queue; elem ; elem = elem->next)
2766 process_one_cond_exec (elem);
2769 /* If we have any DEFINE_SUBST patterns, expand DEFINE_INSN and
2770 DEFINE_EXPAND patterns appropriately. */
2772 static void
2773 process_define_subst (void)
2775 class queue_elem *elem, *elem_attr;
2777 /* Check if each define_subst has corresponding define_subst_attr. */
2778 for (elem = define_subst_queue; elem ; elem = elem->next)
2780 for (elem_attr = define_subst_attr_queue;
2781 elem_attr;
2782 elem_attr = elem_attr->next)
2783 if (strcmp (XSTR (elem->data, 0), XSTR (elem_attr->data, 1)) == 0)
2784 goto found;
2786 error_at (elem->loc,
2787 "%s: `define_subst' must have at least one "
2788 "corresponding `define_subst_attr'",
2789 XSTR (elem->data, 0));
2790 return;
2792 found:
2793 continue;
2796 for (elem = define_insn_queue; elem ; elem = elem->next)
2797 process_substs_on_one_elem (elem, define_insn_queue);
2798 for (elem = other_queue; elem ; elem = elem->next)
2800 if (GET_CODE (elem->data) != DEFINE_EXPAND)
2801 continue;
2802 process_substs_on_one_elem (elem, other_queue);
2806 /* A subclass of rtx_reader which reads .md files and calls process_rtx on
2807 the top-level elements. */
2809 class gen_reader : public rtx_reader
2811 public:
2812 gen_reader () : rtx_reader (false) {}
2813 void handle_unknown_directive (file_location, const char *) final override;
2816 void
2817 gen_reader::handle_unknown_directive (file_location loc, const char *rtx_name)
2819 auto_vec<rtx, 32> subrtxs;
2820 if (!read_rtx (rtx_name, &subrtxs))
2821 return;
2823 rtx x;
2824 unsigned int i;
2825 FOR_EACH_VEC_ELT (subrtxs, i, x)
2826 process_rtx (x, loc);
2829 /* Add mnemonic STR with length LEN to the mnemonic hash table
2830 MNEMONIC_HTAB. A trailing zero end character is appended to STR
2831 and a permanent heap copy of STR is created. */
2833 static void
2834 add_mnemonic_string (htab_t mnemonic_htab, const char *str, size_t len)
2836 char *new_str;
2837 void **slot;
2838 char *str_zero = (char*)alloca (len + 1);
2840 memcpy (str_zero, str, len);
2841 str_zero[len] = '\0';
2843 slot = htab_find_slot (mnemonic_htab, str_zero, INSERT);
2845 if (*slot)
2846 return;
2848 /* Not found; create a permanent copy and add it to the hash table. */
2849 new_str = XNEWVAR (char, len + 1);
2850 memcpy (new_str, str_zero, len + 1);
2851 *slot = new_str;
2854 /* Scan INSN for mnemonic strings and add them to the mnemonic hash
2855 table in MNEMONIC_HTAB.
2857 The mnemonics cannot be found if they are emitted using C code.
2859 If a mnemonic string contains ';' or a newline the string assumed
2860 to consist of more than a single instruction. The attribute value
2861 will then be set to the user defined default value. */
2863 static void
2864 gen_mnemonic_setattr (htab_t mnemonic_htab, rtx insn)
2866 const char *template_code, *cp;
2867 int i;
2868 int vec_len;
2869 rtx set_attr;
2870 char *attr_name;
2871 rtvec new_vec;
2872 struct obstack *string_obstack = rtx_reader_ptr->get_string_obstack ();
2874 template_code = XTMPL (insn, 3);
2876 /* Skip patterns which use C code to emit the template. */
2877 if (template_code[0] == '*')
2878 return;
2880 if (template_code[0] == '@')
2881 cp = &template_code[1];
2882 else
2883 cp = &template_code[0];
2885 for (i = 0; *cp; )
2887 const char *ep, *sp;
2888 size_t size = 0;
2890 while (ISSPACE (*cp))
2891 cp++;
2893 for (ep = sp = cp; !IS_VSPACE (*ep) && *ep != '\0'; ++ep)
2894 if (!ISSPACE (*ep))
2895 sp = ep + 1;
2897 if (i > 0)
2898 obstack_1grow (string_obstack, ',');
2900 while (cp < sp && ((*cp >= '0' && *cp <= '9')
2901 || (*cp >= 'a' && *cp <= 'z')))
2904 obstack_1grow (string_obstack, *cp);
2905 cp++;
2906 size++;
2909 while (cp < sp)
2911 if (*cp == ';' || (*cp == '\\' && cp[1] == 'n'))
2913 /* Don't set a value if there are more than one
2914 instruction in the string. */
2915 obstack_blank_fast (string_obstack, -size);
2916 size = 0;
2918 cp = sp;
2919 break;
2921 cp++;
2923 if (size == 0)
2924 obstack_1grow (string_obstack, '*');
2925 else
2926 add_mnemonic_string (mnemonic_htab,
2927 (char *) obstack_next_free (string_obstack) - size,
2928 size);
2929 i++;
2932 /* An insn definition might emit an empty string. */
2933 if (obstack_object_size (string_obstack) == 0)
2934 return;
2936 obstack_1grow (string_obstack, '\0');
2938 set_attr = rtx_alloc (SET_ATTR);
2939 XSTR (set_attr, 1) = XOBFINISH (string_obstack, char *);
2940 attr_name = XNEWVAR (char, strlen (MNEMONIC_ATTR_NAME) + 1);
2941 strcpy (attr_name, MNEMONIC_ATTR_NAME);
2942 XSTR (set_attr, 0) = attr_name;
2944 if (!XVEC (insn, 4))
2945 vec_len = 0;
2946 else
2947 vec_len = XVECLEN (insn, 4);
2949 new_vec = rtvec_alloc (vec_len + 1);
2950 for (i = 0; i < vec_len; i++)
2951 RTVEC_ELT (new_vec, i) = XVECEXP (insn, 4, i);
2952 RTVEC_ELT (new_vec, vec_len) = set_attr;
2953 XVEC (insn, 4) = new_vec;
2956 /* This function is called for the elements in the mnemonic hashtable
2957 and generates a comma separated list of the mnemonics. */
2959 static int
2960 mnemonic_htab_callback (void **slot, void *info ATTRIBUTE_UNUSED)
2962 struct obstack *string_obstack = rtx_reader_ptr->get_string_obstack ();
2964 obstack_grow (string_obstack, (char*) *slot, strlen ((char*) *slot));
2965 obstack_1grow (string_obstack, ',');
2966 return 1;
2969 /* Generate (set_attr "mnemonic" "..") RTXs and append them to every
2970 insn definition in case the back end requests it by defining the
2971 mnemonic attribute. The values for the attribute will be extracted
2972 from the output patterns of the insn definitions as far as
2973 possible. */
2975 static void
2976 gen_mnemonic_attr (void)
2978 class queue_elem *elem;
2979 rtx mnemonic_attr = NULL;
2980 htab_t mnemonic_htab;
2981 const char *str, *p;
2982 int i;
2983 struct obstack *string_obstack = rtx_reader_ptr->get_string_obstack ();
2985 if (have_error)
2986 return;
2988 /* Look for the DEFINE_ATTR for `mnemonic'. */
2989 for (elem = define_attr_queue; elem != *define_attr_tail; elem = elem->next)
2990 if (GET_CODE (elem->data) == DEFINE_ATTR
2991 && strcmp (XSTR (elem->data, 0), MNEMONIC_ATTR_NAME) == 0)
2993 mnemonic_attr = elem->data;
2994 break;
2997 /* A (define_attr "mnemonic" "...") indicates that the back-end
2998 wants a mnemonic attribute to be generated. */
2999 if (!mnemonic_attr)
3000 return;
3002 mnemonic_htab = htab_create_alloc (MNEMONIC_HTAB_SIZE, htab_hash_string,
3003 htab_eq_string, 0, xcalloc, free);
3005 for (elem = define_insn_queue; elem; elem = elem->next)
3007 rtx insn = elem->data;
3008 bool found = false;
3010 /* Check if the insn definition already has
3011 (set_attr "mnemonic" ...) or (set (attr "mnemonic") ...). */
3012 if (XVEC (insn, 4))
3013 for (i = 0; i < XVECLEN (insn, 4); i++)
3015 rtx set_attr = XVECEXP (insn, 4, i);
3017 switch (GET_CODE (set_attr))
3019 case SET_ATTR:
3020 case SET_ATTR_ALTERNATIVE:
3021 if (strcmp (XSTR (set_attr, 0), MNEMONIC_ATTR_NAME) == 0)
3022 found = true;
3023 break;
3024 case SET:
3025 if (GET_CODE (SET_DEST (set_attr)) == ATTR
3026 && strcmp (XSTR (SET_DEST (set_attr), 0),
3027 MNEMONIC_ATTR_NAME) == 0)
3028 found = true;
3029 break;
3030 default:
3031 break;
3035 if (!found)
3036 gen_mnemonic_setattr (mnemonic_htab, insn);
3039 /* Add the user defined values to the hash table. */
3040 str = XSTR (mnemonic_attr, 1);
3041 while ((p = scan_comma_elt (&str)) != NULL)
3042 add_mnemonic_string (mnemonic_htab, p, str - p);
3044 htab_traverse (mnemonic_htab, mnemonic_htab_callback, NULL);
3046 /* Replace the last ',' with the zero end character. */
3047 *((char *) obstack_next_free (string_obstack) - 1) = '\0';
3048 XSTR (mnemonic_attr, 1) = XOBFINISH (string_obstack, char *);
3051 /* Check if there are DEFINE_ATTRs with the same name. */
3052 static void
3053 check_define_attr_duplicates ()
3055 class queue_elem *elem;
3056 htab_t attr_htab;
3057 char * attr_name;
3058 void **slot;
3060 attr_htab = htab_create (500, htab_hash_string, htab_eq_string, NULL);
3062 for (elem = define_attr_queue; elem; elem = elem->next)
3064 attr_name = xstrdup (XSTR (elem->data, 0));
3066 slot = htab_find_slot (attr_htab, attr_name, INSERT);
3068 /* Duplicate. */
3069 if (*slot)
3071 error_at (elem->loc, "redefinition of attribute '%s'", attr_name);
3072 htab_delete (attr_htab);
3073 return;
3076 *slot = attr_name;
3079 htab_delete (attr_htab);
3082 /* The entry point for initializing the reader. */
3084 rtx_reader *
3085 init_rtx_reader_args_cb (int argc, const char **argv,
3086 bool (*parse_opt) (const char *))
3088 /* Prepare to read input. */
3089 condition_table = htab_create (500, hash_c_test, cmp_c_test, NULL);
3090 init_predicate_table ();
3091 obstack_init (rtl_obstack);
3093 /* Start at 1, to make 0 available for CODE_FOR_nothing. */
3094 insn_sequence_num = 1;
3096 /* These sequences are not used as indices, so can start at 1 also. */
3097 split_sequence_num = 1;
3098 peephole2_sequence_num = 1;
3100 gen_reader *reader = new gen_reader ();
3101 reader->read_md_files (argc, argv, parse_opt);
3103 if (define_attr_queue != NULL)
3104 check_define_attr_duplicates ();
3106 /* Process define_cond_exec patterns. */
3107 if (define_cond_exec_queue != NULL)
3108 process_define_cond_exec ();
3110 /* Process define_subst patterns. */
3111 if (define_subst_queue != NULL)
3112 process_define_subst ();
3114 if (define_attr_queue != NULL)
3115 gen_mnemonic_attr ();
3117 if (have_error)
3119 delete reader;
3120 return NULL;
3123 return reader;
3126 /* Programs that don't have their own options can use this entry point
3127 instead. */
3128 rtx_reader *
3129 init_rtx_reader_args (int argc, const char **argv)
3131 return init_rtx_reader_args_cb (argc, argv, 0);
3134 /* Try to read a single rtx from the file. Return true on success,
3135 describing it in *INFO. */
3137 bool
3138 read_md_rtx (md_rtx_info *info)
3140 int truth, *counter;
3141 rtx def;
3143 /* Discard insn patterns which we know can never match (because
3144 their C test is provably always false). If insn_elision is
3145 false, our caller needs to see all the patterns. Note that the
3146 elided patterns are never counted by the sequence numbering; it
3147 is the caller's responsibility, when insn_elision is false, not
3148 to use elided pattern numbers for anything. */
3151 class queue_elem **queue, *elem;
3153 /* Read all patterns from a given queue before moving on to the next. */
3154 if (define_attr_queue != NULL)
3155 queue = &define_attr_queue;
3156 else if (define_pred_queue != NULL)
3157 queue = &define_pred_queue;
3158 else if (define_insn_queue != NULL)
3159 queue = &define_insn_queue;
3160 else if (other_queue != NULL)
3161 queue = &other_queue;
3162 else
3163 return false;
3165 elem = *queue;
3166 *queue = elem->next;
3167 def = elem->data;
3168 info->def = def;
3169 info->loc = elem->loc;
3170 free (elem);
3172 truth = maybe_eval_c_test (get_c_test (def));
3174 while (truth == 0 && insn_elision);
3176 /* Perform code-specific processing and pick the appropriate sequence
3177 number counter. */
3178 switch (GET_CODE (def))
3180 case DEFINE_INSN:
3181 case DEFINE_EXPAND:
3182 /* insn_sequence_num is used here so the name table will match caller's
3183 idea of insn numbering, whether or not elision is active. */
3184 record_insn_name (insn_sequence_num, XSTR (def, 0));
3186 /* Fall through. */
3187 case DEFINE_PEEPHOLE:
3188 counter = &insn_sequence_num;
3189 break;
3191 case DEFINE_SPLIT:
3192 counter = &split_sequence_num;
3193 break;
3195 case DEFINE_PEEPHOLE2:
3196 counter = &peephole2_sequence_num;
3197 break;
3199 default:
3200 counter = NULL;
3201 break;
3204 if (counter)
3206 info->index = *counter;
3207 if (truth != 0)
3208 *counter += 1;
3210 else
3211 info->index = -1;
3213 if (!rtx_locs)
3214 rtx_locs = new hash_map <rtx, file_location>;
3215 rtx_locs->put (info->def, info->loc);
3217 return true;
3220 /* Return the file location of DEFINE_* rtx X, which was previously
3221 returned by read_md_rtx. */
3222 file_location
3223 get_file_location (rtx x)
3225 gcc_assert (rtx_locs);
3226 file_location *entry = rtx_locs->get (x);
3227 gcc_assert (entry);
3228 return *entry;
3231 /* Return the number of possible INSN_CODEs. Only meaningful once the
3232 whole file has been processed. */
3233 unsigned int
3234 get_num_insn_codes ()
3236 return insn_sequence_num;
3239 /* Return the C test that says whether definition rtx DEF can be used,
3240 or "" if it can be used unconditionally. */
3242 const char *
3243 get_c_test (rtx x)
3245 switch (GET_CODE (x))
3247 case DEFINE_INSN:
3248 case DEFINE_EXPAND:
3249 case DEFINE_SUBST:
3250 return XSTR (x, 2);
3252 case DEFINE_SPLIT:
3253 case DEFINE_PEEPHOLE:
3254 case DEFINE_PEEPHOLE2:
3255 return XSTR (x, 1);
3257 default:
3258 return "";
3262 /* Helper functions for insn elision. */
3264 /* Compute a hash function of a c_test structure, which is keyed
3265 by its ->expr field. */
3266 hashval_t
3267 hash_c_test (const void *x)
3269 const struct c_test *a = (const struct c_test *) x;
3270 const unsigned char *base, *s = (const unsigned char *) a->expr;
3271 hashval_t hash;
3272 unsigned char c;
3273 unsigned int len;
3275 base = s;
3276 hash = 0;
3278 while ((c = *s++) != '\0')
3280 hash += c + (c << 17);
3281 hash ^= hash >> 2;
3284 len = s - base;
3285 hash += len + (len << 17);
3286 hash ^= hash >> 2;
3288 return hash;
3291 /* Compare two c_test expression structures. */
3293 cmp_c_test (const void *x, const void *y)
3295 const struct c_test *a = (const struct c_test *) x;
3296 const struct c_test *b = (const struct c_test *) y;
3298 return !strcmp (a->expr, b->expr);
3301 /* Given a string representing a C test expression, look it up in the
3302 condition_table and report whether or not its value is known
3303 at compile time. Returns a tristate: 1 for known true, 0 for
3304 known false, -1 for unknown. */
3306 maybe_eval_c_test (const char *expr)
3308 const struct c_test *test;
3309 struct c_test dummy;
3311 if (expr[0] == 0)
3312 return 1;
3314 dummy.expr = expr;
3315 test = (const struct c_test *)htab_find (condition_table, &dummy);
3316 if (!test)
3317 return -1;
3318 return test->value;
3321 /* Record the C test expression EXPR in the condition_table, with
3322 value VAL. Duplicates clobber previous entries. */
3324 void
3325 add_c_test (const char *expr, int value)
3327 struct c_test *test;
3329 if (expr[0] == 0)
3330 return;
3332 test = XNEW (struct c_test);
3333 test->expr = expr;
3334 test->value = value;
3336 *(htab_find_slot (condition_table, test, INSERT)) = test;
3339 /* For every C test, call CALLBACK with two arguments: a pointer to
3340 the condition structure and INFO. Stops when CALLBACK returns zero. */
3341 void
3342 traverse_c_tests (htab_trav callback, void *info)
3344 if (condition_table)
3345 htab_traverse (condition_table, callback, info);
3348 /* Helper functions for define_predicate and define_special_predicate
3349 processing. Shared between genrecog.cc and genpreds.cc. */
3351 static htab_t predicate_table;
3352 struct pred_data *first_predicate;
3353 static struct pred_data **last_predicate = &first_predicate;
3355 static hashval_t
3356 hash_struct_pred_data (const void *ptr)
3358 return htab_hash_string (((const struct pred_data *)ptr)->name);
3361 static int
3362 eq_struct_pred_data (const void *a, const void *b)
3364 return !strcmp (((const struct pred_data *)a)->name,
3365 ((const struct pred_data *)b)->name);
3368 struct pred_data *
3369 lookup_predicate (const char *name)
3371 struct pred_data key;
3372 key.name = name;
3373 return (struct pred_data *) htab_find (predicate_table, &key);
3376 /* Record that predicate PRED can accept CODE. */
3378 void
3379 add_predicate_code (struct pred_data *pred, enum rtx_code code)
3381 if (!pred->codes[code])
3383 pred->num_codes++;
3384 pred->codes[code] = true;
3386 if (GET_RTX_CLASS (code) != RTX_CONST_OBJ)
3387 pred->allows_non_const = true;
3389 if (code != REG
3390 && code != SUBREG
3391 && code != MEM
3392 && code != CONCAT
3393 && code != PARALLEL
3394 && code != STRICT_LOW_PART
3395 && code != ZERO_EXTRACT
3396 && code != SCRATCH)
3397 pred->allows_non_lvalue = true;
3399 if (pred->num_codes == 1)
3400 pred->singleton = code;
3401 else if (pred->num_codes == 2)
3402 pred->singleton = UNKNOWN;
3406 void
3407 add_predicate (struct pred_data *pred)
3409 void **slot = htab_find_slot (predicate_table, pred, INSERT);
3410 if (*slot)
3412 error ("duplicate predicate definition for '%s'", pred->name);
3413 return;
3415 *slot = pred;
3416 *last_predicate = pred;
3417 last_predicate = &pred->next;
3420 /* This array gives the initial content of the predicate table. It
3421 has entries for all predicates defined in recog.cc. */
3423 struct std_pred_table
3425 const char *name;
3426 bool special;
3427 bool allows_const_p;
3428 RTX_CODE codes[NUM_RTX_CODE];
3431 static const struct std_pred_table std_preds[] = {
3432 {"general_operand", false, true, {SUBREG, REG, MEM}},
3433 {"address_operand", true, true, {SUBREG, REG, MEM, PLUS, MINUS, MULT,
3434 ZERO_EXTEND, SIGN_EXTEND, AND}},
3435 {"register_operand", false, false, {SUBREG, REG}},
3436 {"pmode_register_operand", true, false, {SUBREG, REG}},
3437 {"scratch_operand", false, false, {SCRATCH, REG}},
3438 {"immediate_operand", false, true, {UNKNOWN}},
3439 {"const_int_operand", false, false, {CONST_INT}},
3440 #if TARGET_SUPPORTS_WIDE_INT
3441 {"const_scalar_int_operand", false, false, {CONST_INT, CONST_WIDE_INT}},
3442 {"const_double_operand", false, false, {CONST_DOUBLE}},
3443 #else
3444 {"const_double_operand", false, false, {CONST_INT, CONST_DOUBLE}},
3445 #endif
3446 {"nonimmediate_operand", false, false, {SUBREG, REG, MEM}},
3447 {"nonmemory_operand", false, true, {SUBREG, REG}},
3448 {"push_operand", false, false, {MEM}},
3449 {"pop_operand", false, false, {MEM}},
3450 {"memory_operand", false, false, {SUBREG, MEM}},
3451 {"indirect_operand", false, false, {SUBREG, MEM}},
3452 {"ordered_comparison_operator", false, false, {EQ, NE,
3453 LE, LT, GE, GT,
3454 LEU, LTU, GEU, GTU}},
3455 {"comparison_operator", false, false, {EQ, NE,
3456 LE, LT, GE, GT,
3457 LEU, LTU, GEU, GTU,
3458 UNORDERED, ORDERED,
3459 UNEQ, UNGE, UNGT,
3460 UNLE, UNLT, LTGT}}
3462 #define NUM_KNOWN_STD_PREDS ARRAY_SIZE (std_preds)
3464 /* Initialize the table of predicate definitions, starting with
3465 the information we have on generic predicates. */
3467 static void
3468 init_predicate_table (void)
3470 size_t i, j;
3471 struct pred_data *pred;
3473 predicate_table = htab_create_alloc (37, hash_struct_pred_data,
3474 eq_struct_pred_data, 0,
3475 xcalloc, free);
3477 for (i = 0; i < NUM_KNOWN_STD_PREDS; i++)
3479 pred = XCNEW (struct pred_data);
3480 pred->name = std_preds[i].name;
3481 pred->special = std_preds[i].special;
3483 for (j = 0; std_preds[i].codes[j] != 0; j++)
3484 add_predicate_code (pred, std_preds[i].codes[j]);
3486 if (std_preds[i].allows_const_p)
3487 for (j = 0; j < NUM_RTX_CODE; j++)
3488 if (GET_RTX_CLASS (j) == RTX_CONST_OBJ)
3489 add_predicate_code (pred, (enum rtx_code) j);
3491 add_predicate (pred);
3495 /* These functions allow linkage with print-rtl.cc. Also, some generators
3496 like to annotate their output with insn names. */
3498 /* Holds an array of names indexed by insn_code_number. */
3499 static char **insn_name_ptr = 0;
3500 static int insn_name_ptr_size = 0;
3502 const char *
3503 get_insn_name (int code)
3505 if (code < insn_name_ptr_size)
3506 return insn_name_ptr[code];
3507 else
3508 return NULL;
3511 static void
3512 record_insn_name (int code, const char *name)
3514 static const char *last_real_name = "insn";
3515 static int last_real_code = 0;
3516 char *new_name;
3518 if (insn_name_ptr_size <= code)
3520 int new_size;
3521 new_size = (insn_name_ptr_size ? insn_name_ptr_size * 2 : 512);
3522 insn_name_ptr = XRESIZEVEC (char *, insn_name_ptr, new_size);
3523 memset (insn_name_ptr + insn_name_ptr_size, 0,
3524 sizeof (char *) * (new_size - insn_name_ptr_size));
3525 insn_name_ptr_size = new_size;
3528 if (!name || name[0] == '\0')
3530 new_name = XNEWVAR (char, strlen (last_real_name) + 10);
3531 sprintf (new_name, "%s+%d", last_real_name, code - last_real_code);
3533 else
3535 last_real_name = new_name = xstrdup (name);
3536 last_real_code = code;
3539 insn_name_ptr[code] = new_name;
3542 /* Make STATS describe the operands that appear in rtx X. */
3544 static void
3545 get_pattern_stats_1 (struct pattern_stats *stats, rtx x)
3547 RTX_CODE code;
3548 int i;
3549 int len;
3550 const char *fmt;
3552 if (x == NULL_RTX)
3553 return;
3555 code = GET_CODE (x);
3556 switch (code)
3558 case MATCH_OPERAND:
3559 case MATCH_OPERATOR:
3560 case MATCH_PARALLEL:
3561 stats->max_opno = MAX (stats->max_opno, XINT (x, 0));
3562 break;
3564 case MATCH_DUP:
3565 case MATCH_OP_DUP:
3566 case MATCH_PAR_DUP:
3567 stats->num_dups++;
3568 stats->max_dup_opno = MAX (stats->max_dup_opno, XINT (x, 0));
3569 break;
3571 case MATCH_SCRATCH:
3572 if (stats->min_scratch_opno == -1)
3573 stats->min_scratch_opno = XINT (x, 0);
3574 else
3575 stats->min_scratch_opno = MIN (stats->min_scratch_opno, XINT (x, 0));
3576 stats->max_scratch_opno = MAX (stats->max_scratch_opno, XINT (x, 0));
3577 break;
3579 default:
3580 break;
3583 fmt = GET_RTX_FORMAT (code);
3584 len = GET_RTX_LENGTH (code);
3585 for (i = 0; i < len; i++)
3587 if (fmt[i] == 'e' || fmt[i] == 'u')
3588 get_pattern_stats_1 (stats, XEXP (x, i));
3589 else if (fmt[i] == 'E')
3591 int j;
3592 for (j = 0; j < XVECLEN (x, i); j++)
3593 get_pattern_stats_1 (stats, XVECEXP (x, i, j));
3598 /* Make STATS describe the operands that appear in instruction pattern
3599 PATTERN. */
3601 void
3602 get_pattern_stats (struct pattern_stats *stats, rtvec pattern)
3604 int i, len;
3606 stats->max_opno = -1;
3607 stats->max_dup_opno = -1;
3608 stats->min_scratch_opno = -1;
3609 stats->max_scratch_opno = -1;
3610 stats->num_dups = 0;
3612 len = GET_NUM_ELEM (pattern);
3613 for (i = 0; i < len; i++)
3614 get_pattern_stats_1 (stats, RTVEC_ELT (pattern, i));
3616 stats->num_generator_args = stats->max_opno + 1;
3617 stats->num_insn_operands = MAX (stats->max_opno,
3618 stats->max_scratch_opno) + 1;
3619 stats->num_operand_vars = MAX (stats->max_opno,
3620 MAX (stats->max_dup_opno,
3621 stats->max_scratch_opno)) + 1;
3624 /* Return the emit_* function that should be used for pattern X, or NULL
3625 if we can't pick a particular type at compile time and should instead
3626 fall back to "emit". */
3628 const char *
3629 get_emit_function (rtx x)
3631 switch (classify_insn (x))
3633 case INSN:
3634 return "emit_insn";
3636 case CALL_INSN:
3637 return "emit_call_insn";
3639 case JUMP_INSN:
3640 return "emit_jump_insn";
3642 case UNKNOWN:
3643 return NULL;
3645 default:
3646 gcc_unreachable ();
3650 /* Return true if we must emit a barrier after pattern X. */
3652 bool
3653 needs_barrier_p (rtx x)
3655 return (GET_CODE (x) == SET
3656 && GET_CODE (SET_DEST (x)) == PC
3657 && GET_CODE (SET_SRC (x)) == LABEL_REF);
3660 #define NS "NULL"
3661 #define ZS "'\\0'"
3662 #define OPTAB_CL(o, p, c, b, l) { #o, p, #b, ZS, #l, o, c, UNKNOWN, 1 },
3663 #define OPTAB_CX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 1 },
3664 #define OPTAB_CD(o, p) { #o, p, NS, ZS, NS, o, UNKNOWN, UNKNOWN, 2 },
3665 #define OPTAB_NL(o, p, c, b, s, l) { #o, p, #b, #s, #l, o, c, c, 3 },
3666 #define OPTAB_NC(o, p, c) { #o, p, NS, ZS, NS, o, c, c, 3 },
3667 #define OPTAB_NX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 3 },
3668 #define OPTAB_VL(o, p, c, b, s, l) { #o, p, #b, #s, #l, o, c, UNKNOWN, 3 },
3669 #define OPTAB_VC(o, p, c) { #o, p, NS, ZS, NS, o, c, UNKNOWN, 3 },
3670 #define OPTAB_VX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 3 },
3671 #define OPTAB_DC(o, p, c) { #o, p, NS, ZS, NS, o, c, c, 4 },
3672 #define OPTAB_D(o, p) { #o, p, NS, ZS, NS, o, UNKNOWN, UNKNOWN, 4 },
3674 /* An array of all optabs. Note that the same optab can appear more
3675 than once, with a different pattern. */
3676 optab_def optabs[] = {
3677 { "unknown_optab", NULL, NS, ZS, NS, unknown_optab, UNKNOWN, UNKNOWN, 0 },
3678 #include "optabs.def"
3681 /* The number of entries in optabs[]. */
3682 unsigned int num_optabs = ARRAY_SIZE (optabs);
3684 #undef OPTAB_CL
3685 #undef OPTAB_CX
3686 #undef OPTAB_CD
3687 #undef OPTAB_NL
3688 #undef OPTAB_NC
3689 #undef OPTAB_NX
3690 #undef OPTAB_VL
3691 #undef OPTAB_VC
3692 #undef OPTAB_VX
3693 #undef OPTAB_DC
3694 #undef OPTAB_D
3696 /* Return true if instruction NAME matches pattern PAT, storing information
3697 about the match in P if so. */
3699 static bool
3700 match_pattern (optab_pattern *p, const char *name, const char *pat)
3702 bool force_float = false;
3703 bool force_int = false;
3704 bool force_partial_int = false;
3705 bool force_fixed = false;
3707 if (pat == NULL)
3708 return false;
3709 for (; ; ++pat)
3711 if (*pat != '$')
3713 if (*pat != *name++)
3714 return false;
3715 if (*pat == '\0')
3716 return true;
3717 continue;
3719 switch (*++pat)
3721 case 'I':
3722 force_int = 1;
3723 break;
3724 case 'P':
3725 force_partial_int = 1;
3726 break;
3727 case 'F':
3728 force_float = 1;
3729 break;
3730 case 'Q':
3731 force_fixed = 1;
3732 break;
3734 case 'a':
3735 case 'b':
3737 int i;
3739 /* This loop will stop at the first prefix match, so
3740 look through the modes in reverse order, in case
3741 there are extra CC modes and CC is a prefix of the
3742 CC modes (as it should be). */
3743 for (i = (MAX_MACHINE_MODE) - 1; i >= 0; i--)
3745 const char *p, *q;
3746 for (p = GET_MODE_NAME (i), q = name; *p; p++, q++)
3747 if (TOLOWER (*p) != *q)
3748 break;
3749 if (*p == 0
3750 && (! force_int || mode_class[i] == MODE_INT
3751 || mode_class[i] == MODE_VECTOR_INT)
3752 && (! force_partial_int
3753 || mode_class[i] == MODE_INT
3754 || mode_class[i] == MODE_PARTIAL_INT
3755 || mode_class[i] == MODE_VECTOR_INT)
3756 && (! force_float
3757 || mode_class[i] == MODE_FLOAT
3758 || mode_class[i] == MODE_DECIMAL_FLOAT
3759 || mode_class[i] == MODE_COMPLEX_FLOAT
3760 || mode_class[i] == MODE_VECTOR_FLOAT)
3761 && (! force_fixed
3762 || mode_class[i] == MODE_FRACT
3763 || mode_class[i] == MODE_UFRACT
3764 || mode_class[i] == MODE_ACCUM
3765 || mode_class[i] == MODE_UACCUM
3766 || mode_class[i] == MODE_VECTOR_FRACT
3767 || mode_class[i] == MODE_VECTOR_UFRACT
3768 || mode_class[i] == MODE_VECTOR_ACCUM
3769 || mode_class[i] == MODE_VECTOR_UACCUM))
3770 break;
3773 if (i < 0)
3774 return false;
3775 name += strlen (GET_MODE_NAME (i));
3776 if (*pat == 'a')
3777 p->m1 = i;
3778 else
3779 p->m2 = i;
3781 force_int = false;
3782 force_partial_int = false;
3783 force_float = false;
3784 force_fixed = false;
3786 break;
3788 default:
3789 gcc_unreachable ();
3794 /* Return true if NAME is the name of an optab, describing it in P if so. */
3796 bool
3797 find_optab (optab_pattern *p, const char *name)
3799 if (*name == 0 || *name == '*')
3800 return false;
3802 /* See if NAME matches one of the patterns we have for the optabs
3803 we know about. */
3804 for (unsigned int pindex = 0; pindex < ARRAY_SIZE (optabs); pindex++)
3806 p->m1 = p->m2 = 0;
3807 if (match_pattern (p, name, optabs[pindex].pattern))
3809 p->name = name;
3810 p->op = optabs[pindex].op;
3811 p->sort_num = (p->op << 20) | (p->m2 << 10) | p->m1;
3812 return true;
3815 return false;