1 /* Support routines for the various generation passes.
2 Copyright (C) 2000-2025 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)
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/>. */
21 #define INCLUDE_STRING
22 #define INCLUDE_VECTOR
24 #include "coretypes.h"
30 #include "gensupport.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. */
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. */
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
*,
112 static char *shift_output_template (char *, const char *, int);
113 static const char *alter_output_for_insn (class queue_elem
*,
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
*,
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
),
144 rtx rt
= rtx_alloc (CONST_INT
);
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);
160 rtx pattern
= rtx_alloc (PARALLEL
);
161 XVEC (pattern
, 0) = vec
;
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
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. */
206 #define TRISTATE_AND(a,b) \
207 ((a) == I ? ((b) == N ? N : I) : \
208 (b) == I ? ((a) == N ? N : I) : \
211 #define TRISTATE_OR(a,b) \
212 ((a) == I ? ((b) == Y ? Y : I) : \
213 (b) == I ? ((a) == Y ? Y : I) : \
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. */
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
];
234 switch (GET_CODE (exp
))
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
]);
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
]);
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
]);
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
]),
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
);
276 memset (codes
, N
, NUM_RTX_CODE
);
278 const char *next_code
= XSTR (exp
, 0);
281 if (*next_code
== '\0')
283 error_at (loc
, "empty match_code expression");
287 while ((code
= scan_comma_elt (&next_code
)) != 0)
289 size_t n
= next_code
- code
;
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')
302 error_at (loc
, "match_code \"%.*s\" matches nothing",
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\"?)",
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));
325 error_at (loc
, "reference to unknown predicate '%s'",
329 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
330 codes
[i
] = p
->codes
[i
] ? I
: N
;
336 /* (match_test WHATEVER) is completely indeterminate. */
337 memset (codes
, I
, NUM_RTX_CODE
);
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
);
352 /* Return true if NAME is a valid predicate name. */
355 valid_predicate_name_p (const char *name
)
359 if (!ISALPHA (name
[0]) && name
[0] != '_')
361 for (p
= name
+ 1; *p
; p
++)
362 if (!ISALNUM (*p
) && *p
!= '_')
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
372 process_define_predicate (rtx desc
, file_location loc
)
374 struct pred_data
*pred
;
375 char codes
[NUM_RTX_CODE
];
378 if (!valid_predicate_name_p (XSTR (desc
, 0)))
380 error_at (loc
, "%s: predicate name must be a valid C function name",
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
++)
396 add_predicate_code (pred
, (enum rtx_code
) i
);
398 add_predicate (pred
);
404 /* Maps register filter conditions to the associated filter identifier. */
405 static hash_map
<nofree_string_hash
, unsigned int> register_filter_map
;
407 /* All register filter conditions, indexed by identifier. */
408 vec
<const char *> register_filters
;
410 /* Return the unique identifier for filter condition FILTER. Identifiers
411 are assigned automatically when the define_register_constraint is
415 get_register_filter_id (const char *filter
)
417 unsigned int *slot
= register_filter_map
.get (filter
);
422 /* Process define_register_constraint directive DESC, at location LOC. */
425 process_define_register_constraint (rtx desc
, file_location loc
)
427 /* Assign identifiers to each unique register filter condition. */
428 if (const char *filter
= XSTR (desc
, 3))
430 bool existed
= false;
431 unsigned int &id
= register_filter_map
.get_or_insert (filter
, &existed
);
434 id
= register_filters
.length ();
436 fatal_at (loc
, "too many distinct register filters, maximum"
438 register_filters
.safe_push (filter
);
443 /* Queue PATTERN on LIST_TAIL. Return the address of the new queue
446 static class queue_elem
*
447 queue_pattern (rtx pattern
, class queue_elem
***list_tail
,
450 class queue_elem
*e
= XNEW (class queue_elem
);
456 *list_tail
= &e
->next
;
460 /* Remove element ELEM from QUEUE. */
462 remove_from_queue (class queue_elem
*elem
, class queue_elem
**queue
)
464 class queue_elem
*prev
, *e
;
466 for (e
= *queue
; e
; e
= e
->next
)
476 prev
->next
= elem
->next
;
481 /* Build a define_attr for an binary attribute with name NAME and
482 possible values "yes" and "no", and queue it. */
484 add_define_attr (const char *name
)
486 class queue_elem
*e
= XNEW (class queue_elem
);
487 rtx t1
= rtx_alloc (DEFINE_ATTR
);
489 XSTR (t1
, 1) = "no,yes";
490 XEXP (t1
, 2) = rtx_alloc (CONST_STRING
);
491 XSTR (XEXP (t1
, 2), 0) = "yes";
493 e
->loc
= file_location ("built-in", -1, -1);
494 e
->next
= define_attr_queue
;
495 define_attr_queue
= e
;
499 /* Recursively remove constraints from an rtx. */
502 remove_constraints (rtx part
)
505 const char *format_ptr
;
510 if (GET_CODE (part
) == MATCH_OPERAND
)
512 else if (GET_CODE (part
) == MATCH_SCRATCH
)
515 format_ptr
= GET_RTX_FORMAT (GET_CODE (part
));
517 for (i
= 0; i
< GET_RTX_LENGTH (GET_CODE (part
)); i
++)
518 switch (*format_ptr
++)
522 remove_constraints (XEXP (part
, i
));
525 if (XVEC (part
, i
) != NULL
)
526 for (j
= 0; j
< XVECLEN (part
, i
); j
++)
527 remove_constraints (XVECEXP (part
, i
, j
));
532 /* Recursively replace MATCH_OPERANDs with MATCH_DUPs and MATCH_OPERATORs
533 with MATCH_OP_DUPs in X. */
536 replace_operands_with_dups (rtx x
)
542 if (GET_CODE (x
) == MATCH_OPERAND
)
544 newx
= rtx_alloc (MATCH_DUP
);
545 XINT (newx
, 0) = XINT (x
, 0);
548 else if (GET_CODE (x
) == MATCH_OPERATOR
)
550 newx
= rtx_alloc (MATCH_OP_DUP
);
551 XINT (newx
, 0) = XINT (x
, 0);
552 XVEC (newx
, 1) = XVEC (x
, 2);
556 newx
= shallow_copy_rtx (x
);
558 const char *format_ptr
= GET_RTX_FORMAT (GET_CODE (x
));
559 for (int i
= 0; i
< GET_RTX_LENGTH (GET_CODE (x
)); i
++)
560 switch (*format_ptr
++)
564 XEXP (newx
, i
) = replace_operands_with_dups (XEXP (x
, i
));
567 if (XVEC (x
, i
) != NULL
)
569 XVEC (newx
, i
) = rtvec_alloc (XVECLEN (x
, i
));
570 for (int j
= 0; j
< XVECLEN (x
, i
); j
++)
572 = replace_operands_with_dups (XVECEXP (x
, i
, j
));
579 /* Convert matching pattern VEC from a DEFINE_INSN_AND_REWRITE into
580 a sequence that should be generated by the splitter. */
583 gen_rewrite_sequence (rtvec vec
)
585 rtvec new_vec
= rtvec_alloc (1);
586 rtx x
= add_implicit_parallel (vec
);
587 RTVEC_ELT (new_vec
, 0) = replace_operands_with_dups (x
);
591 /* The following is for handling the compact syntax for constraints and
594 The normal syntax looks like this:
597 (match_operand: 0 "s_register_operand" "r,I,k")
598 (match_operand: 2 "s_register_operand" "r,k,I")
605 (set_attr "length" "4,8,8")
607 The compact syntax looks like this:
610 (match_operand: 0 "s_register_operand")
611 (match_operand: 2 "s_register_operand")
613 {@ [cons: 0, 2; attrs: length]
621 This is the only place where this syntax needs to be handled. Relevant
622 patterns are transformed from compact to the normal syntax before they are
623 queued, so none of the gen* programs need to know about this syntax at all.
625 Conversion process (convert_syntax):
627 0) Check that pattern actually uses new syntax (check for {@ ... }).
629 1) Get the "layout", i.e. the "[cons: 0 2; attrs: length]" from the above
630 example. cons must come first; both are optional. Set up two vecs,
631 convec and attrvec, for holding the results of the transformation.
633 2) For each alternative: parse the list of constraints and/or attributes,
634 and enqueue them in the relevant lists in convec and attrvec. By the end
635 of this process, convec[N].con and attrvec[N].con should contain regular
636 syntax constraint/attribute lists like "r,I,k". Copy the asm to a string
639 3) Search the rtx and write the constraint and attribute lists into the
640 correct places. Write the asm back into the template. */
642 /* Helper class for shuffling constraints/attributes in convert_syntax and
643 add_constraints/add_attributes. This includes commas but not whitespace. */
653 conlist () = default;
655 /* [ns..ns + len) should be a string with the id of the rtx to match
656 i.e. if rtx is the relevant match_operand or match_scratch then
657 [ns..ns + len) should equal itoa (XINT (rtx, 0)), and if set_attr then
658 [ns..ns + len) should equal XSTR (rtx, 0). */
659 conlist (const char *ns
, unsigned int len
, bool numeric
)
661 /* Trim leading whitespaces. */
662 while (len
> 0 && ISBLANK (*ns
))
668 /* Trim trailing whitespace. */
669 for (int i
= len
- 1; i
>= 0; i
--, len
--)
670 if (!ISBLANK (ns
[i
]))
673 /* Parse off any modifiers. */
674 while (len
> 0 && !ISALNUM (*ns
))
680 name
.assign (ns
, len
);
682 idx
= strtol (name
.c_str (), (char **)NULL
, 10);
685 /* Adds a character to the end of the string. */
691 /* Output the string in the form of a brand-new char *, then effectively
692 clear the internal string by resetting len to 0. */
695 /* Final character is always a trailing comma, so strip it out. */
696 char *q
= xstrndup (con
.c_str (), con
.size () - 1);
702 typedef std::vector
<conlist
> vec_conlist
;
704 /* Add constraints to an rtx. This function is similar to remove_constraints.
705 Errors if adding the constraints would overwrite existing constraints. */
708 add_constraints (rtx part
, file_location loc
, vec_conlist
&cons
)
710 const char *format_ptr
;
712 if (part
== NULL_RTX
)
715 /* If match_op or match_scr, check if we have the right one, and if so, copy
716 over the constraint list. */
717 if (GET_CODE (part
) == MATCH_OPERAND
|| GET_CODE (part
) == MATCH_SCRATCH
)
719 int field
= GET_CODE (part
) == MATCH_OPERAND
? 2 : 1;
720 unsigned id
= XINT (part
, 0);
722 if (id
>= cons
.size () || cons
[id
].idx
== -1)
725 if (XSTR (part
, field
)[0] != '\0')
727 error_at (loc
, "can't mix normal and compact constraint syntax");
730 XSTR (part
, field
) = cons
[id
].out ();
734 format_ptr
= GET_RTX_FORMAT (GET_CODE (part
));
736 /* Recursively search the rtx. */
737 for (int i
= 0; i
< GET_RTX_LENGTH (GET_CODE (part
)); i
++)
738 switch (*format_ptr
++)
742 add_constraints (XEXP (part
, i
), loc
, cons
);
745 if (XVEC (part
, i
) != NULL
)
746 for (int j
= 0; j
< XVECLEN (part
, i
); j
++)
747 add_constraints (XVECEXP (part
, i
, j
), loc
, cons
);
754 /* Add ATTRS to definition X's attribute list. */
757 add_attributes (rtx x
, vec_conlist
&attrs
)
759 unsigned int attr_index
= GET_CODE (x
) == DEFINE_INSN
? 4 : 3;
760 rtvec orig
= XVEC (x
, attr_index
);
763 size_t n_curr
= XVECLEN (x
, attr_index
);
764 rtvec copy
= rtvec_alloc (n_curr
+ attrs
.size ());
766 /* Create a shallow copy of existing entries. */
767 memcpy (©
->elem
[attrs
.size ()], &orig
->elem
[0],
768 sizeof (rtx
) * n_curr
);
769 XVEC (x
, attr_index
) = copy
;
772 XVEC (x
, attr_index
) = rtvec_alloc (attrs
.size ());
774 /* Create the new elements. */
775 for (unsigned i
= 0; i
< attrs
.size (); i
++)
777 rtx attr
= rtx_alloc (SET_ATTR
);
778 XSTR (attr
, 0) = xstrdup (attrs
[i
].name
.c_str ());
779 XSTR (attr
, 1) = attrs
[i
].out ();
780 XVECEXP (x
, attr_index
, i
) = attr
;
784 /* Consumes spaces and tabs. */
787 skip_spaces (const char **str
)
789 while (ISBLANK (**str
))
793 /* Consumes the given character, if it's there. */
796 expect_char (const char **str
, char c
)
804 /* Parses the section layout that follows a "{@" if using new syntax. Builds
805 a vector for a single section. E.g. if we have "attrs: length, arch]..."
806 then list will have two elements, the first for "length" and the second
810 parse_section_layout (file_location loc
, const char **templ
, const char *label
,
811 vec_conlist
&list
, bool numeric
)
813 const char *name_start
;
814 size_t label_len
= strlen (label
);
815 if (strncmp (label
, *templ
, label_len
) == 0)
819 /* Gather the names. */
820 while (**templ
!= ';' && **templ
!= ']')
825 char val
= (*templ
)[len
];
826 while (val
!= ',' && val
!= ';' && val
!= ']')
828 if (val
== 0 || val
== '\n')
829 fatal_at (loc
, "missing ']'");
830 val
= (*templ
)[++len
];
835 list
.push_back (conlist (name_start
, len
, numeric
));
840 /* Parse a section, a section is defined as a named space separated list, e.g.
844 is a section named "foo" with entries a, b and c. */
847 parse_section (const char **templ
, unsigned int n_elems
, unsigned int alt_no
,
848 vec_conlist
&list
, file_location loc
, const char *name
)
852 /* Go through the list, one character at a time, adding said character
853 to the correct string. */
854 for (i
= 0; **templ
!= ']' && **templ
!= ';'; (*templ
)++)
855 if (!ISBLANK (**templ
))
857 if (**templ
== 0 || **templ
== '\n')
858 fatal_at (loc
, "missing ']'");
859 list
[i
].add (**templ
);
864 fatal_at (loc
, "too many %ss in alternative %d: expected %d",
865 name
, alt_no
, n_elems
);
870 fatal_at (loc
, "too few %ss in alternative %d: expected %d, got %d",
871 name
, alt_no
, n_elems
, i
);
876 /* The compact syntax has more convience syntaxes. As such we post process
877 the lines to get them back to something the normal syntax understands. */
880 preprocess_compact_syntax (file_location loc
, int alt_no
, std::string
&line
,
881 std::string
&last_line
)
883 /* Check if we're copying the last statement. */
884 if (line
.find ("^") == 0 && line
.size () == 1)
886 if (last_line
.empty ())
887 fatal_at (loc
, "found instruction to copy previous line (^) in"
888 "alternative %d but no previous line to copy", alt_no
);
895 /* Check if we have << which means return c statement. */
896 if (line
.find ("<<") == 0)
898 result
.append ("* return ");
899 const char *chunk
= line
.c_str () + 2;
900 skip_spaces (&chunk
);
901 result
.append (chunk
);
904 result
.append (line
);
910 /* Converts an rtx from compact syntax to normal syntax if possible. */
913 convert_syntax (rtx x
, file_location loc
)
916 unsigned int templ_index
;
918 vec_conlist tconvec
, convec
, attrvec
;
921 gcc_assert (GET_CODE (x
) == DEFINE_INSN
);
923 templ
= XTMPL (x
, templ_index
);
925 /* Templates with constraints start with "{@". */
926 if (strncmp ("*{@", templ
, 3))
929 /* Get the layout for the template. */
931 skip_spaces (&templ
);
933 if (!expect_char (&templ
, '['))
934 fatal_at (loc
, "expecing `[' to begin section list");
936 skip_spaces (&templ
);
938 parse_section_layout (loc
, &templ
, "cons:", tconvec
, true);
943 skip_spaces (&(++templ
));
944 parse_section_layout (loc
, &templ
, "attrs:", attrvec
, false);
947 if (!expect_char (&templ
, ']'))
948 fatal_at (loc
, "expecting `]` to end section list - section list must have "
949 "cons first, attrs second");
951 /* We will write the un-constrainified template into new_templ. */
952 std::string new_templ
;
953 new_templ
.append ("@");
955 /* Skip to the first proper line. */
956 skip_spaces (&templ
);
958 fatal_at (loc
, "'{@...}' blocks must have at least one alternative");
960 fatal_at (loc
, "unexpected character '%c' after ']'", *templ
);
964 std::string last_line
;
966 /* Process the alternatives. */
967 while (*(templ
- 1) != '\0')
969 /* Skip leading whitespace. */
971 skip_spaces (&templ
);
973 /* Check if we're at the end. */
974 if (templ
[0] == '}' && templ
[1] == '\0')
977 if (expect_char (&templ
, '['))
980 new_templ
.append (buffer
);
981 /* Parse the constraint list, then the attribute list. */
982 if (tconvec
.size () > 0)
983 parse_section (&templ
, tconvec
.size (), alt_no
, tconvec
, loc
,
986 if (attrvec
.size () > 0)
988 if (tconvec
.size () > 0 && !expect_char (&templ
, ';'))
989 fatal_at (loc
, "expected `;' to separate constraints "
990 "and attributes in alternative %d", alt_no
);
992 parse_section (&templ
, attrvec
.size (), alt_no
,
993 attrvec
, loc
, "attribute");
996 if (!expect_char (&templ
, ']'))
997 fatal_at (loc
, "expected end of constraint/attribute list but "
998 "missing an ending `]' in alternative %d", alt_no
);
1000 else if (templ
[0] == '/' && templ
[1] == '/')
1003 /* Glob till newline or end of string. */
1004 while (*templ
!= '\n' || *templ
!= '\0')
1007 /* Skip any newlines or whitespaces needed. */
1008 while (ISSPACE(*templ
))
1012 else if (templ
[0] == '/' && templ
[1] == '*')
1015 /* Glob till newline or end of multiline comment. */
1016 while (templ
[0] != 0 && templ
[0] != '*' && templ
[1] != '/')
1019 while (templ
[0] != '*' || templ
[1] != '/')
1022 fatal_at (loc
, "unterminated '/*'");
1027 /* Skip any newlines or whitespaces needed. */
1028 while (ISSPACE(*templ
))
1033 fatal_at (loc
, "expected constraint/attribute list at beginning of "
1034 "alternative %d but missing a starting `['", alt_no
);
1036 /* Skip whitespace between list and asm. */
1037 skip_spaces (&templ
);
1039 /* Copy asm to new template. */
1041 while (*templ
!= '\n' && *templ
!= '\0')
1044 /* Apply any pre-processing needed to the line. */
1045 preprocess_compact_syntax (loc
, alt_no
, line
, last_line
);
1046 new_templ
.append (line
);
1049 /* Normal "*..." syntax expects the closing quote to be on the final
1050 line of asm, whereas we allow the closing "}" to be on its own line.
1051 Postpone copying the '\n' until we know that there is another
1052 alternative in the list. */
1053 while (ISSPACE (*templ
))
1058 /* Check for any duplicate cons entries and sort based on i. */
1059 for (auto e
: tconvec
)
1061 unsigned idx
= e
.idx
;
1062 if (idx
>= convec
.size ())
1063 convec
.resize (idx
+ 1);
1065 if (convec
[idx
].idx
>= 0)
1066 fatal_at (loc
, "duplicate cons number found: %d", idx
);
1071 /* Write the constraints and attributes into their proper places. */
1072 if (convec
.size () > 0)
1073 add_constraints (x
, loc
, convec
);
1075 if (attrvec
.size () > 0)
1076 add_attributes (x
, attrvec
);
1078 /* Copy over the new un-constrainified template. */
1079 XTMPL (x
, templ_index
) = xstrdup (new_templ
.c_str ());
1081 /* Register for later checks during iterator expansions. */
1082 compact_syntax
.add (x
);
1085 /* Process a top level rtx in some way, queuing as appropriate. */
1088 process_rtx (rtx desc
, file_location loc
)
1090 switch (GET_CODE (desc
))
1093 convert_syntax (desc
, loc
);
1094 queue_pattern (desc
, &define_insn_tail
, loc
);
1097 case DEFINE_COND_EXEC
:
1098 queue_pattern (desc
, &define_cond_exec_tail
, loc
);
1102 queue_pattern (desc
, &define_subst_tail
, loc
);
1105 case DEFINE_SUBST_ATTR
:
1106 queue_pattern (desc
, &define_subst_attr_tail
, loc
);
1110 case DEFINE_ENUM_ATTR
:
1111 queue_pattern (desc
, &define_attr_tail
, loc
);
1114 case DEFINE_PREDICATE
:
1115 case DEFINE_SPECIAL_PREDICATE
:
1116 process_define_predicate (desc
, loc
);
1117 queue_pattern (desc
, &define_pred_tail
, loc
);
1120 case DEFINE_REGISTER_CONSTRAINT
:
1121 process_define_register_constraint (desc
, loc
);
1122 queue_pattern (desc
, &define_pred_tail
, loc
);
1125 case DEFINE_CONSTRAINT
:
1126 case DEFINE_MEMORY_CONSTRAINT
:
1127 case DEFINE_SPECIAL_MEMORY_CONSTRAINT
:
1128 case DEFINE_RELAXED_MEMORY_CONSTRAINT
:
1129 case DEFINE_ADDRESS_CONSTRAINT
:
1130 queue_pattern (desc
, &define_pred_tail
, loc
);
1133 case DEFINE_INSN_AND_SPLIT
:
1134 case DEFINE_INSN_AND_REWRITE
:
1136 const char *split_cond
;
1140 class queue_elem
*insn_elem
;
1141 class queue_elem
*split_elem
;
1142 int split_code
= (GET_CODE (desc
) == DEFINE_INSN_AND_REWRITE
? 5 : 6);
1144 /* Create a split with values from the insn_and_split. */
1145 split
= rtx_alloc (DEFINE_SPLIT
);
1147 i
= XVECLEN (desc
, 1);
1148 XVEC (split
, 0) = rtvec_alloc (i
);
1151 XVECEXP (split
, 0, i
) = copy_rtx (XVECEXP (desc
, 1, i
));
1152 remove_constraints (XVECEXP (split
, 0, i
));
1155 /* If the split condition starts with "&&", append it to the
1156 insn condition to create the new split condition. */
1157 split_cond
= XSTR (desc
, 4);
1158 if (split_cond
[0] == '&' && split_cond
[1] == '&')
1160 rtx_reader_ptr
->copy_md_ptr_loc (split_cond
+ 2, split_cond
);
1161 split_cond
= rtx_reader_ptr
->join_c_conditions (XSTR (desc
, 2),
1164 else if (GET_CODE (desc
) == DEFINE_INSN_AND_REWRITE
)
1165 error_at (loc
, "the rewrite condition must start with `&&'");
1166 XSTR (split
, 1) = split_cond
;
1167 if (GET_CODE (desc
) == DEFINE_INSN_AND_REWRITE
)
1168 XVEC (split
, 2) = gen_rewrite_sequence (XVEC (desc
, 1));
1170 XVEC (split
, 2) = XVEC (desc
, 5);
1171 XSTR (split
, 3) = XSTR (desc
, split_code
);
1173 /* Fix up the DEFINE_INSN. */
1174 attr
= XVEC (desc
, split_code
+ 1);
1175 PUT_CODE (desc
, DEFINE_INSN
);
1176 XVEC (desc
, 4) = attr
;
1177 convert_syntax (desc
, loc
);
1180 insn_elem
= queue_pattern (desc
, &define_insn_tail
, loc
);
1181 split_elem
= queue_pattern (split
, &other_tail
, loc
);
1182 insn_elem
->split
= split_elem
;
1187 queue_pattern (desc
, &other_tail
, loc
);
1192 /* Return true if attribute PREDICABLE is true for ELEM, which holds
1196 is_predicable (class queue_elem
*elem
)
1198 rtvec vec
= XVEC (elem
->data
, 4);
1203 return predicable_default
;
1205 for (i
= GET_NUM_ELEM (vec
) - 1; i
>= 0; --i
)
1207 rtx sub
= RTVEC_ELT (vec
, i
);
1208 switch (GET_CODE (sub
))
1211 if (strcmp (XSTR (sub
, 0), "predicable") == 0)
1213 value
= XSTR (sub
, 1);
1218 case SET_ATTR_ALTERNATIVE
:
1219 if (strcmp (XSTR (sub
, 0), "predicable") == 0)
1221 error_at (elem
->loc
, "multiple alternatives for `predicable'");
1227 if (GET_CODE (SET_DEST (sub
)) != ATTR
1228 || strcmp (XSTR (SET_DEST (sub
), 0), "predicable") != 0)
1230 sub
= SET_SRC (sub
);
1231 if (GET_CODE (sub
) == CONST_STRING
)
1233 value
= XSTR (sub
, 0);
1237 /* ??? It would be possible to handle this if we really tried.
1238 It's not easy though, and I'm not going to bother until it
1239 really proves necessary. */
1240 error_at (elem
->loc
, "non-constant value for `predicable'");
1248 return predicable_default
;
1251 /* Find out which value we're looking at. Multiple alternatives means at
1252 least one is predicable. */
1253 if (strchr (value
, ',') != NULL
)
1255 if (strcmp (value
, predicable_true
) == 0)
1257 if (strcmp (value
, predicable_false
) == 0)
1260 error_at (elem
->loc
, "unknown value `%s' for `predicable' attribute", value
);
1264 /* Find attribute SUBST in ELEM and assign NEW_VALUE to it. */
1266 change_subst_attribute (class queue_elem
*elem
,
1267 class queue_elem
*subst_elem
,
1268 const char *new_value
)
1270 rtvec attrs_vec
= XVEC (elem
->data
, 4);
1271 const char *subst_name
= XSTR (subst_elem
->data
, 0);
1277 for (i
= GET_NUM_ELEM (attrs_vec
) - 1; i
>= 0; --i
)
1279 rtx cur_attr
= RTVEC_ELT (attrs_vec
, i
);
1280 if (GET_CODE (cur_attr
) != SET_ATTR
)
1282 if (strcmp (XSTR (cur_attr
, 0), subst_name
) == 0)
1284 XSTR (cur_attr
, 1) = new_value
;
1290 /* Return true if ELEM has the attribute with the name of DEFINE_SUBST
1291 represented by SUBST_ELEM and this attribute has value SUBST_TRUE.
1292 DEFINE_SUBST isn't applied to patterns without such attribute. In other
1293 words, we suppose the default value of the attribute to be 'no' since it is
1294 always generated automatically in read-rtl.cc. */
1296 has_subst_attribute (class queue_elem
*elem
, class queue_elem
*subst_elem
)
1298 rtvec attrs_vec
= XVEC (elem
->data
, 4);
1299 const char *value
, *subst_name
= XSTR (subst_elem
->data
, 0);
1305 for (i
= GET_NUM_ELEM (attrs_vec
) - 1; i
>= 0; --i
)
1307 rtx cur_attr
= RTVEC_ELT (attrs_vec
, i
);
1308 switch (GET_CODE (cur_attr
))
1311 if (strcmp (XSTR (cur_attr
, 0), subst_name
) == 0)
1313 value
= XSTR (cur_attr
, 1);
1319 if (GET_CODE (SET_DEST (cur_attr
)) != ATTR
1320 || strcmp (XSTR (SET_DEST (cur_attr
), 0), subst_name
) != 0)
1322 cur_attr
= SET_SRC (cur_attr
);
1323 if (GET_CODE (cur_attr
) == CONST_STRING
)
1325 value
= XSTR (cur_attr
, 0);
1329 /* Only (set_attr "subst" "yes/no") and
1330 (set (attr "subst" (const_string "yes/no")))
1331 are currently allowed. */
1332 error_at (elem
->loc
, "unsupported value for `%s'", subst_name
);
1335 case SET_ATTR_ALTERNATIVE
:
1336 if (strcmp (XSTR (cur_attr
, 0), subst_name
) == 0)
1337 error_at (elem
->loc
,
1338 "%s: `set_attr_alternative' is unsupported by "
1339 "`define_subst'", XSTR (elem
->data
, 0));
1351 if (strcmp (value
, subst_true
) == 0)
1353 if (strcmp (value
, subst_false
) == 0)
1356 error_at (elem
->loc
, "unknown value `%s' for `%s' attribute",
1361 /* Compare RTL-template of original define_insn X to input RTL-template of
1362 define_subst PT. Return 1 if the templates match, 0 otherwise.
1363 During the comparison, the routine also fills global_array OPERAND_DATA. */
1365 subst_pattern_match (rtx x
, rtx pt
, file_location loc
)
1367 RTX_CODE code
, code_pt
;
1369 const char *fmt
, *pred_name
;
1371 code
= GET_CODE (x
);
1372 code_pt
= GET_CODE (pt
);
1374 if (code_pt
== MATCH_OPERAND
)
1376 /* MATCH_DUP, and MATCH_OP_DUP don't have a specified mode, so we
1377 always accept them. */
1378 if (GET_MODE (pt
) != VOIDmode
&& GET_MODE (x
) != GET_MODE (pt
)
1379 && (code
!= MATCH_DUP
&& code
!= MATCH_OP_DUP
))
1380 return false; /* Modes don't match. */
1382 if (code
== MATCH_OPERAND
)
1384 pred_name
= XSTR (pt
, 1);
1385 if (pred_name
[0] != 0)
1387 const struct pred_data
*pred_pt
= lookup_predicate (pred_name
);
1388 if (!pred_pt
|| pred_pt
!= lookup_predicate (XSTR (x
, 1)))
1389 return false; /* Predicates don't match. */
1393 gcc_assert (XINT (pt
, 0) >= 0 && XINT (pt
, 0) < MAX_OPERANDS
);
1394 operand_data
[XINT (pt
, 0)] = x
;
1398 if (code_pt
== MATCH_OPERATOR
)
1400 int x_vecexp_pos
= -1;
1402 /* Compare modes. */
1403 if (GET_MODE (pt
) != VOIDmode
&& GET_MODE (x
) != GET_MODE (pt
))
1406 /* In case X is also match_operator, compare predicates. */
1407 if (code
== MATCH_OPERATOR
)
1409 pred_name
= XSTR (pt
, 1);
1410 if (pred_name
[0] != 0)
1412 const struct pred_data
*pred_pt
= lookup_predicate (pred_name
);
1413 if (!pred_pt
|| pred_pt
!= lookup_predicate (XSTR (x
, 1)))
1418 /* Compare operands.
1419 MATCH_OPERATOR in input template could match in original template
1420 either 1) MATCH_OPERAND, 2) UNSPEC, 3) ordinary operation (like PLUS).
1421 In the first case operands are at (XVECEXP (x, 2, j)), in the second
1422 - at (XVECEXP (x, 0, j)), in the last one - (XEXP (x, j)).
1423 X_VECEXP_POS variable shows, where to look for these operands. */
1425 || code
== UNSPEC_VOLATILE
)
1427 else if (code
== MATCH_OPERATOR
)
1432 /* MATCH_OPERATOR or UNSPEC case. */
1433 if (x_vecexp_pos
>= 0)
1435 /* Compare operands number in X and PT. */
1436 if (XVECLEN (x
, x_vecexp_pos
) != XVECLEN (pt
, 2))
1438 for (j
= 0; j
< XVECLEN (pt
, 2); j
++)
1439 if (!subst_pattern_match (XVECEXP (x
, x_vecexp_pos
, j
),
1440 XVECEXP (pt
, 2, j
), loc
))
1444 /* Ordinary operator. */
1447 /* Compare operands number in X and PT.
1448 We count operands differently for X and PT since we compare
1449 an operator (with operands directly in RTX) and MATCH_OPERATOR
1450 (that has a vector with operands). */
1451 if (GET_RTX_LENGTH (code
) != XVECLEN (pt
, 2))
1453 for (j
= 0; j
< XVECLEN (pt
, 2); j
++)
1454 if (!subst_pattern_match (XEXP (x
, j
), XVECEXP (pt
, 2, j
), loc
))
1458 /* Store the operand to OPERAND_DATA array. */
1459 gcc_assert (XINT (pt
, 0) >= 0 && XINT (pt
, 0) < MAX_OPERANDS
);
1460 operand_data
[XINT (pt
, 0)] = x
;
1464 if (code_pt
== MATCH_PAR_DUP
1465 || code_pt
== MATCH_DUP
1466 || code_pt
== MATCH_OP_DUP
1467 || code_pt
== MATCH_SCRATCH
1468 || code_pt
== MATCH_PARALLEL
)
1470 /* Currently interface for these constructions isn't defined -
1471 probably they aren't needed in input template of define_subst at all.
1472 So, for now their usage in define_subst is forbidden. */
1473 error_at (loc
, "%s cannot be used in define_subst",
1474 GET_RTX_NAME (code_pt
));
1477 gcc_assert (code
!= MATCH_PAR_DUP
1478 && code_pt
!= MATCH_DUP
1479 && code_pt
!= MATCH_OP_DUP
1480 && code_pt
!= MATCH_SCRATCH
1481 && code_pt
!= MATCH_PARALLEL
1482 && code_pt
!= MATCH_OPERAND
1483 && code_pt
!= MATCH_OPERATOR
);
1484 /* If PT is none of the handled above, then we match only expressions with
1485 the same code in X. */
1486 if (code
!= code_pt
)
1489 fmt
= GET_RTX_FORMAT (code_pt
);
1490 len
= GET_RTX_LENGTH (code_pt
);
1492 for (i
= 0; i
< len
; i
++)
1499 case 'r': case 'p': case 'i': case 'w': case 's': case 'L':
1503 if (!subst_pattern_match (XEXP (x
, i
), XEXP (pt
, i
), loc
))
1508 if (XVECLEN (x
, i
) != XVECLEN (pt
, i
))
1510 for (j
= 0; j
< XVECLEN (pt
, i
); j
++)
1511 if (!subst_pattern_match (XVECEXP (x
, i
, j
),
1512 XVECEXP (pt
, i
, j
), loc
))
1524 /* Examine the attribute "predicable"; discover its boolean values
1528 identify_predicable_attribute (void)
1530 class queue_elem
*elem
;
1531 char *p_true
, *p_false
;
1534 /* Look for the DEFINE_ATTR for `predicable', which must exist. */
1535 for (elem
= define_attr_queue
; elem
; elem
= elem
->next
)
1536 if (strcmp (XSTR (elem
->data
, 0), "predicable") == 0)
1539 error_at (define_cond_exec_queue
->loc
,
1540 "attribute `predicable' not defined");
1544 value
= XSTR (elem
->data
, 1);
1545 p_false
= xstrdup (value
);
1546 p_true
= strchr (p_false
, ',');
1547 if (p_true
== NULL
|| strchr (++p_true
, ',') != NULL
)
1549 error_at (elem
->loc
, "attribute `predicable' is not a boolean");
1555 predicable_true
= p_true
;
1556 predicable_false
= p_false
;
1558 switch (GET_CODE (XEXP (elem
->data
, 2)))
1561 value
= XSTR (XEXP (elem
->data
, 2), 0);
1565 error_at (elem
->loc
, "attribute `predicable' cannot be const");
1570 error_at (elem
->loc
,
1571 "attribute `predicable' must have a constant default");
1576 if (strcmp (value
, p_true
) == 0)
1577 predicable_default
= 1;
1578 else if (strcmp (value
, p_false
) == 0)
1579 predicable_default
= 0;
1582 error_at (elem
->loc
, "unknown value `%s' for `predicable' attribute",
1588 /* Return the number of alternatives in constraint S. */
1591 n_alternatives (const char *s
)
1602 /* The routine scans rtl PATTERN, find match_operand in it and counts
1603 number of alternatives. If PATTERN contains several match_operands
1604 with different number of alternatives, error is emitted, and the
1605 routine returns 0. If all match_operands in PATTERN have the same
1606 number of alternatives, it's stored in N_ALT, and the routine returns 1.
1607 LOC is the location of PATTERN, for error reporting. */
1609 get_alternatives_number (rtx pattern
, int *n_alt
, file_location loc
)
1618 code
= GET_CODE (pattern
);
1622 i
= n_alternatives (XSTR (pattern
, 2));
1623 /* n_alternatives returns 1 if constraint string is empty -
1624 here we fix it up. */
1625 if (!*(XSTR (pattern
, 2)))
1630 else if (i
&& i
!= *n_alt
)
1632 error_at (loc
, "wrong number of alternatives in operand %d",
1641 fmt
= GET_RTX_FORMAT (code
);
1642 len
= GET_RTX_LENGTH (code
);
1643 for (i
= 0; i
< len
; i
++)
1648 if (!get_alternatives_number (XEXP (pattern
, i
), n_alt
, loc
))
1653 if (XVEC (pattern
, i
) == NULL
)
1658 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
1659 if (!get_alternatives_number (XVECEXP (pattern
, i
, j
), n_alt
, loc
))
1663 case 'r': case 'p': case 'i': case 'w':
1664 case '0': case 's': case 'S': case 'T':
1675 /* Determine how many alternatives there are in INSN, and how many
1679 collect_insn_data (rtx pattern
, int *palt
, int *pmax
)
1685 code
= GET_CODE (pattern
);
1690 i
= n_alternatives (XSTR (pattern
, code
== MATCH_SCRATCH
? 1 : 2));
1691 *palt
= (i
> *palt
? i
: *palt
);
1694 case MATCH_OPERATOR
:
1695 case MATCH_PARALLEL
:
1696 i
= XINT (pattern
, 0);
1705 fmt
= GET_RTX_FORMAT (code
);
1706 len
= GET_RTX_LENGTH (code
);
1707 for (i
= 0; i
< len
; i
++)
1712 collect_insn_data (XEXP (pattern
, i
), palt
, pmax
);
1716 if (XVEC (pattern
, i
) == NULL
)
1720 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
1721 collect_insn_data (XVECEXP (pattern
, i
, j
), palt
, pmax
);
1724 case 'r': case 'p': case 'i': case 'w':
1725 case '0': case 's': case 'S': case 'T':
1736 alter_predicate_for_insn (rtx pattern
, int alt
, int max_op
,
1743 code
= GET_CODE (pattern
);
1748 const char *c
= XSTR (pattern
, 2);
1750 if (n_alternatives (c
) != 1)
1752 error_at (loc
, "too many alternatives for operand %d",
1757 /* Replicate C as needed to fill out ALT alternatives. */
1758 if (c
&& *c
&& alt
> 1)
1760 size_t c_len
= strlen (c
);
1761 size_t len
= alt
* (c_len
+ 1);
1762 char *new_c
= XNEWVEC (char, len
);
1764 memcpy (new_c
, c
, c_len
);
1765 for (i
= 1; i
< alt
; ++i
)
1767 new_c
[i
* (c_len
+ 1) - 1] = ',';
1768 memcpy (&new_c
[i
* (c_len
+ 1)], c
, c_len
);
1770 new_c
[len
- 1] = '\0';
1771 XSTR (pattern
, 2) = new_c
;
1776 case MATCH_OPERATOR
:
1778 case MATCH_PARALLEL
:
1780 XINT (pattern
, 0) += max_op
;
1787 fmt
= GET_RTX_FORMAT (code
);
1788 len
= GET_RTX_LENGTH (code
);
1789 for (i
= 0; i
< len
; i
++)
1796 r
= alter_predicate_for_insn (XEXP (pattern
, i
), alt
, max_op
, loc
);
1802 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
1804 r
= alter_predicate_for_insn (XVECEXP (pattern
, i
, j
),
1811 case 'r': case 'p': case 'i': case 'w': case '0': case 's': case 'L':
1822 /* Duplicate constraints in PATTERN. If pattern is from original
1823 rtl-template, we need to duplicate each alternative - for that we
1824 need to use duplicate_each_alternative () as a functor ALTER.
1825 If pattern is from output-pattern of define_subst, we need to
1826 duplicate constraints in another way - with duplicate_alternatives ().
1827 N_DUP is multiplication factor. */
1829 alter_constraints (rtx pattern
, int n_dup
, constraints_handler_t alter
)
1835 code
= GET_CODE (pattern
);
1839 XSTR (pattern
, 2) = alter (XSTR (pattern
, 2), n_dup
);
1842 XSTR (pattern
, 1) = alter (XSTR (pattern
, 1), n_dup
);
1849 fmt
= GET_RTX_FORMAT (code
);
1850 len
= GET_RTX_LENGTH (code
);
1851 for (i
= 0; i
< len
; i
++)
1858 r
= alter_constraints (XEXP (pattern
, i
), n_dup
, alter
);
1864 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
1866 r
= alter_constraints (XVECEXP (pattern
, i
, j
), n_dup
, alter
);
1872 case 'r': case 'p': case 'i': case 'w': case '0': case 's': case 'L':
1884 alter_test_for_insn (class queue_elem
*ce_elem
,
1885 class queue_elem
*insn_elem
)
1887 return rtx_reader_ptr
->join_c_conditions (XSTR (ce_elem
->data
, 1),
1888 XSTR (insn_elem
->data
, 2));
1891 /* Modify VAL, which is an attribute expression for the "enabled" attribute,
1892 to take "ce_enabled" into account. Return the new expression. */
1894 modify_attr_enabled_ce (rtx val
)
1898 eq_attr
= rtx_alloc (EQ_ATTR
);
1899 ite
= rtx_alloc (IF_THEN_ELSE
);
1900 str
= rtx_alloc (CONST_STRING
);
1902 XSTR (eq_attr
, 0) = "ce_enabled";
1903 XSTR (eq_attr
, 1) = "yes";
1904 XSTR (str
, 0) = "no";
1905 XEXP (ite
, 0) = eq_attr
;
1906 XEXP (ite
, 1) = val
;
1907 XEXP (ite
, 2) = str
;
1912 /* Alter the attribute vector of INSN, which is a COND_EXEC variant created
1913 from a define_insn pattern. We must modify the "predicable" attribute
1914 to be named "ce_enabled", and also change any "enabled" attribute that's
1915 present so that it takes ce_enabled into account.
1916 We rely on the fact that INSN was created with copy_rtx, and modify data
1920 alter_attrs_for_insn (rtx insn
)
1922 static bool global_changes_made
= false;
1923 rtvec vec
= XVEC (insn
, 4);
1927 int predicable_idx
= -1;
1928 int enabled_idx
= -1;
1934 num_elem
= GET_NUM_ELEM (vec
);
1935 for (i
= num_elem
- 1; i
>= 0; --i
)
1937 rtx sub
= RTVEC_ELT (vec
, i
);
1938 switch (GET_CODE (sub
))
1941 if (strcmp (XSTR (sub
, 0), "predicable") == 0)
1944 XSTR (sub
, 0) = "ce_enabled";
1946 else if (strcmp (XSTR (sub
, 0), "enabled") == 0)
1949 XSTR (sub
, 0) = "nonce_enabled";
1953 case SET_ATTR_ALTERNATIVE
:
1954 if (strcmp (XSTR (sub
, 0), "predicable") == 0)
1955 /* We already give an error elsewhere. */
1957 else if (strcmp (XSTR (sub
, 0), "enabled") == 0)
1960 XSTR (sub
, 0) = "nonce_enabled";
1965 if (GET_CODE (SET_DEST (sub
)) != ATTR
)
1967 if (strcmp (XSTR (SET_DEST (sub
), 0), "predicable") == 0)
1969 sub
= SET_SRC (sub
);
1970 if (GET_CODE (sub
) == CONST_STRING
)
1973 XSTR (sub
, 0) = "ce_enabled";
1976 /* We already give an error elsewhere. */
1980 if (strcmp (XSTR (SET_DEST (sub
), 0), "enabled") == 0)
1983 XSTR (SET_DEST (sub
), 0) = "nonce_enabled";
1991 if (predicable_idx
== -1)
1994 if (!global_changes_made
)
1996 class queue_elem
*elem
;
1998 global_changes_made
= true;
1999 add_define_attr ("ce_enabled");
2000 add_define_attr ("nonce_enabled");
2002 for (elem
= define_attr_queue
; elem
; elem
= elem
->next
)
2003 if (strcmp (XSTR (elem
->data
, 0), "enabled") == 0)
2005 XEXP (elem
->data
, 2)
2006 = modify_attr_enabled_ce (XEXP (elem
->data
, 2));
2009 if (enabled_idx
== -1)
2012 new_vec
= rtvec_alloc (num_elem
+ 1);
2013 for (i
= 0; i
< num_elem
; i
++)
2014 RTVEC_ELT (new_vec
, i
) = RTVEC_ELT (vec
, i
);
2015 val
= rtx_alloc (IF_THEN_ELSE
);
2016 XEXP (val
, 0) = rtx_alloc (EQ_ATTR
);
2017 XEXP (val
, 1) = rtx_alloc (CONST_STRING
);
2018 XEXP (val
, 2) = rtx_alloc (CONST_STRING
);
2019 XSTR (XEXP (val
, 0), 0) = "nonce_enabled";
2020 XSTR (XEXP (val
, 0), 1) = "yes";
2021 XSTR (XEXP (val
, 1), 0) = "yes";
2022 XSTR (XEXP (val
, 2), 0) = "no";
2023 set
= rtx_alloc (SET
);
2024 SET_DEST (set
) = rtx_alloc (ATTR
);
2025 XSTR (SET_DEST (set
), 0) = "enabled";
2026 SET_SRC (set
) = modify_attr_enabled_ce (val
);
2027 RTVEC_ELT (new_vec
, i
) = set
;
2028 XVEC (insn
, 4) = new_vec
;
2031 /* As number of constraints is changed after define_subst, we need to
2032 process attributes as well - we need to duplicate them the same way
2033 that we duplicated constraints in original pattern
2034 ELEM is a queue element, containing our rtl-template,
2035 N_DUP - multiplication factor. */
2037 alter_attrs_for_subst_insn (class queue_elem
* elem
, int n_dup
)
2039 rtvec vec
= XVEC (elem
->data
, 4);
2043 if (n_dup
< 2 || ! vec
)
2046 num_elem
= GET_NUM_ELEM (vec
);
2047 for (i
= num_elem
- 1; i
>= 0; --i
)
2049 rtx sub
= RTVEC_ELT (vec
, i
);
2050 switch (GET_CODE (sub
))
2053 if (strchr (XSTR (sub
, 1), ',') != NULL
)
2054 XSTR (sub
, 1) = duplicate_alternatives (XSTR (sub
, 1), n_dup
);
2057 case SET_ATTR_ALTERNATIVE
:
2059 error_at (elem
->loc
,
2060 "%s: `define_subst' does not support attributes "
2061 "assigned by `set' and `set_attr_alternative'",
2062 XSTR (elem
->data
, 0));
2071 /* Adjust all of the operand numbers in SRC to match the shift they'll
2072 get from an operand displacement of DISP. Return a pointer after the
2076 shift_output_template (char *dest
, const char *src
, int disp
)
2085 if (ISDIGIT ((unsigned char) c
))
2087 else if (ISALPHA (c
))
2100 alter_output_for_insn (class queue_elem
*ce_elem
,
2101 class queue_elem
*insn_elem
,
2102 int alt
, int max_op
)
2104 const char *ce_out
, *insn_out
;
2106 size_t len
, ce_len
, insn_len
;
2108 /* ??? Could coordinate with genoutput to not duplicate code here. */
2110 ce_out
= XSTR (ce_elem
->data
, 2);
2111 insn_out
= XTMPL (insn_elem
->data
, 3);
2112 if (!ce_out
|| *ce_out
== '\0')
2115 ce_len
= strlen (ce_out
);
2116 insn_len
= strlen (insn_out
);
2118 if (*insn_out
== '*')
2119 /* You must take care of the predicate yourself. */
2122 if (*insn_out
== '@')
2124 len
= (ce_len
+ 1) * alt
+ insn_len
+ 1;
2125 p
= result
= XNEWVEC (char, len
);
2131 while (ISSPACE ((unsigned char) *insn_out
));
2133 if (*insn_out
!= '#')
2135 p
= shift_output_template (p
, ce_out
, max_op
);
2141 while (*insn_out
&& *insn_out
!= '\n');
2148 len
= ce_len
+ 1 + insn_len
+ 1;
2149 result
= XNEWVEC (char, len
);
2151 p
= shift_output_template (result
, ce_out
, max_op
);
2153 memcpy (p
, insn_out
, insn_len
+ 1);
2159 /* From string STR "a,b,c" produce "a,b,c,a,b,c,a,b,c", i.e. original
2160 string, duplicated N_DUP times. */
2163 duplicate_alternatives (const char * str
, int n_dup
)
2165 int i
, len
, new_len
;
2172 while (ISSPACE (*str
))
2180 new_len
= (len
+ 1) * n_dup
;
2182 sp
= result
= XNEWVEC (char, new_len
);
2184 /* Global modifier characters mustn't be duplicated: skip if found. */
2185 if (*cp
== '=' || *cp
== '+' || *cp
== '%')
2191 /* Copy original constraints N_DUP times. */
2192 for (i
= 0; i
< n_dup
; i
++, sp
+= len
+1)
2194 memcpy (sp
, cp
, len
);
2195 *(sp
+len
) = (i
== n_dup
- 1) ? '\0' : ',';
2201 /* From string STR "a,b,c" produce "a,a,a,b,b,b,c,c,c", i.e. string where
2202 each alternative from the original string is duplicated N_DUP times. */
2204 duplicate_each_alternative (const char * str
, int n_dup
)
2206 int i
, len
, new_len
;
2207 char *result
, *sp
, *ep
, *cp
;
2212 while (ISSPACE (*str
))
2220 new_len
= (strlen (cp
) + 1) * n_dup
;
2222 sp
= result
= XNEWVEC (char, new_len
);
2224 /* Global modifier characters mustn't be duplicated: skip if found. */
2225 if (*cp
== '=' || *cp
== '+' || *cp
== '%')
2230 if ((ep
= strchr (cp
, ',')) != NULL
)
2234 /* Copy a constraint N_DUP times. */
2235 for (i
= 0; i
< n_dup
; i
++, sp
+= len
+ 1)
2237 memcpy (sp
, cp
, len
);
2238 *(sp
+len
) = (ep
== NULL
&& i
== n_dup
- 1) ? '\0' : ',';
2248 /* Alter the output of INSN whose pattern was modified by
2249 DEFINE_SUBST. We must replicate output strings according
2250 to the new number of alternatives ALT in substituted pattern.
2251 If ALT equals 1, output has one alternative or defined by C
2252 code, then output is returned without any changes. */
2255 alter_output_for_subst_insn (rtx insn
, int alt
)
2257 const char *insn_out
, *old_out
;
2259 size_t old_len
, new_len
;
2262 insn_out
= XTMPL (insn
, 3);
2264 if (alt
< 2 || *insn_out
!= '@')
2267 old_out
= insn_out
+ 1;
2268 while (ISSPACE (*old_out
))
2270 old_len
= strlen (old_out
);
2272 new_len
= alt
* (old_len
+ 1) + 1;
2274 new_out
= XNEWVEC (char, new_len
);
2277 for (j
= 0, cp
= new_out
+ 1; j
< alt
; j
++, cp
+= old_len
+ 1)
2279 memcpy (cp
, old_out
, old_len
);
2280 cp
[old_len
] = (j
== alt
- 1) ? '\0' : '\n';
2286 /* Replicate insns as appropriate for the given DEFINE_COND_EXEC. */
2289 process_one_cond_exec (class queue_elem
*ce_elem
)
2291 class queue_elem
*insn_elem
;
2292 for (insn_elem
= define_insn_queue
; insn_elem
; insn_elem
= insn_elem
->next
)
2294 int alternatives
, max_operand
;
2295 rtx pred
, insn
, pattern
, split
;
2299 if (! is_predicable (insn_elem
))
2304 collect_insn_data (insn_elem
->data
, &alternatives
, &max_operand
);
2307 if (XVECLEN (ce_elem
->data
, 0) != 1)
2309 error_at (ce_elem
->loc
, "too many patterns in predicate");
2313 pred
= copy_rtx (XVECEXP (ce_elem
->data
, 0, 0));
2314 pred
= alter_predicate_for_insn (pred
, alternatives
, max_operand
,
2319 /* Construct a new pattern for the new insn. */
2320 insn
= copy_rtx (insn_elem
->data
);
2321 new_name
= XNEWVAR (char, strlen
XSTR (insn_elem
->data
, 0) + 4);
2322 sprintf (new_name
, "*p %s", XSTR (insn_elem
->data
, 0));
2323 XSTR (insn
, 0) = new_name
;
2324 pattern
= rtx_alloc (COND_EXEC
);
2325 XEXP (pattern
, 0) = pred
;
2326 XEXP (pattern
, 1) = add_implicit_parallel (XVEC (insn
, 1));
2327 XVEC (insn
, 1) = rtvec_alloc (1);
2328 XVECEXP (insn
, 1, 0) = pattern
;
2330 if (XVEC (ce_elem
->data
, 3) != NULL
)
2332 rtvec attributes
= rtvec_alloc (XVECLEN (insn
, 4)
2333 + XVECLEN (ce_elem
->data
, 3));
2336 for (i
= 0; i
< XVECLEN (insn
, 4); i
++)
2337 RTVEC_ELT (attributes
, i
) = XVECEXP (insn
, 4, i
);
2339 for (j
= 0; j
< XVECLEN (ce_elem
->data
, 3); j
++, i
++)
2340 RTVEC_ELT (attributes
, i
) = XVECEXP (ce_elem
->data
, 3, j
);
2342 XVEC (insn
, 4) = attributes
;
2345 XSTR (insn
, 2) = alter_test_for_insn (ce_elem
, insn_elem
);
2346 XTMPL (insn
, 3) = alter_output_for_insn (ce_elem
, insn_elem
,
2347 alternatives
, max_operand
);
2348 alter_attrs_for_insn (insn
);
2350 /* Put the new pattern on the `other' list so that it
2351 (a) is not reprocessed by other define_cond_exec patterns
2352 (b) appears after all normal define_insn patterns.
2354 ??? B is debatable. If one has normal insns that match
2355 cond_exec patterns, they will be preferred over these
2356 generated patterns. Whether this matters in practice, or if
2357 it's a good thing, or whether we should thread these new
2358 patterns into the define_insn chain just after their generator
2359 is something we'll have to experiment with. */
2361 queue_pattern (insn
, &other_tail
, insn_elem
->loc
);
2363 if (!insn_elem
->split
)
2366 /* If the original insn came from a define_insn_and_split,
2367 generate a new split to handle the predicated insn. */
2368 split
= copy_rtx (insn_elem
->split
->data
);
2369 /* Predicate the pattern matched by the split. */
2370 pattern
= rtx_alloc (COND_EXEC
);
2371 XEXP (pattern
, 0) = pred
;
2372 XEXP (pattern
, 1) = add_implicit_parallel (XVEC (split
, 0));
2373 XVEC (split
, 0) = rtvec_alloc (1);
2374 XVECEXP (split
, 0, 0) = pattern
;
2376 /* Predicate all of the insns generated by the split. */
2377 for (i
= 0; i
< XVECLEN (split
, 2); i
++)
2379 pattern
= rtx_alloc (COND_EXEC
);
2380 XEXP (pattern
, 0) = pred
;
2381 XEXP (pattern
, 1) = XVECEXP (split
, 2, i
);
2382 XVECEXP (split
, 2, i
) = pattern
;
2384 /* Add the new split to the queue. */
2385 queue_pattern (split
, &other_tail
, insn_elem
->split
->loc
);
2389 /* Try to apply define_substs to the given ELEM.
2390 Only define_substs, specified via attributes would be applied.
2391 If attribute, requiring define_subst, is set, but no define_subst
2392 was applied, ELEM would be deleted. */
2395 process_substs_on_one_elem (class queue_elem
*elem
,
2396 class queue_elem
*queue
)
2398 class queue_elem
*subst_elem
;
2399 int i
, j
, patterns_match
;
2401 for (subst_elem
= define_subst_queue
;
2402 subst_elem
; subst_elem
= subst_elem
->next
)
2404 int alternatives
, alternatives_subst
;
2406 rtvec subst_pattern_vec
;
2408 if (!has_subst_attribute (elem
, subst_elem
))
2411 /* Compare original rtl-pattern from define_insn with input
2412 pattern from define_subst.
2413 Also, check if numbers of alternatives are the same in all
2415 if (XVECLEN (elem
->data
, 1) != XVECLEN (subst_elem
->data
, 1))
2419 alternatives_subst
= -1;
2420 for (j
= 0; j
< XVECLEN (elem
->data
, 1); j
++)
2422 if (!subst_pattern_match (XVECEXP (elem
->data
, 1, j
),
2423 XVECEXP (subst_elem
->data
, 1, j
),
2430 if (!get_alternatives_number (XVECEXP (elem
->data
, 1, j
),
2431 &alternatives
, subst_elem
->loc
))
2438 /* Check if numbers of alternatives are the same in all
2439 match_operands in output template of define_subst. */
2440 for (j
= 0; j
< XVECLEN (subst_elem
->data
, 3); j
++)
2442 if (!get_alternatives_number (XVECEXP (subst_elem
->data
, 3, j
),
2443 &alternatives_subst
,
2451 if (!patterns_match
)
2454 /* Clear array in which we save occupied indexes of operands. */
2455 memset (used_operands_numbers
, 0, sizeof (used_operands_numbers
));
2457 /* Create a pattern, based on the output one from define_subst. */
2458 subst_pattern_vec
= rtvec_alloc (XVECLEN (subst_elem
->data
, 3));
2459 for (j
= 0; j
< XVECLEN (subst_elem
->data
, 3); j
++)
2461 subst_pattern
= copy_rtx (XVECEXP (subst_elem
->data
, 3, j
));
2463 /* Duplicate constraints in substitute-pattern. */
2464 subst_pattern
= alter_constraints (subst_pattern
, alternatives
,
2465 duplicate_each_alternative
);
2467 subst_pattern
= adjust_operands_numbers (subst_pattern
);
2469 /* Substitute match_dup and match_op_dup in the new pattern and
2470 duplicate constraints. */
2471 subst_pattern
= subst_dup (subst_pattern
, alternatives
,
2472 alternatives_subst
);
2474 replace_duplicating_operands_in_pattern (subst_pattern
);
2476 /* We don't need any constraints in DEFINE_EXPAND. */
2477 if (GET_CODE (elem
->data
) == DEFINE_EXPAND
)
2478 remove_constraints (subst_pattern
);
2480 RTVEC_ELT (subst_pattern_vec
, j
) = subst_pattern
;
2482 XVEC (elem
->data
, 1) = subst_pattern_vec
;
2484 for (i
= 0; i
< MAX_OPERANDS
; i
++)
2485 match_operand_entries_in_pattern
[i
] = NULL
;
2487 if (GET_CODE (elem
->data
) == DEFINE_INSN
)
2489 XTMPL (elem
->data
, 3) =
2490 alter_output_for_subst_insn (elem
->data
, alternatives_subst
);
2491 alter_attrs_for_subst_insn (elem
, alternatives_subst
);
2494 /* Recalculate condition, joining conditions from original and
2495 DEFINE_SUBST input patterns. */
2496 XSTR (elem
->data
, 2)
2497 = rtx_reader_ptr
->join_c_conditions (XSTR (subst_elem
->data
, 2),
2498 XSTR (elem
->data
, 2));
2499 /* Mark that subst was applied by changing attribute from "yes"
2501 change_subst_attribute (elem
, subst_elem
, subst_false
);
2504 /* If ELEM contains a subst attribute with value "yes", then we
2505 expected that a subst would be applied, but it wasn't - so,
2506 we need to remove that elementto avoid duplicating. */
2507 for (subst_elem
= define_subst_queue
;
2508 subst_elem
; subst_elem
= subst_elem
->next
)
2510 if (has_subst_attribute (elem
, subst_elem
))
2512 remove_from_queue (elem
, &queue
);
2518 /* This is a subroutine of mark_operands_used_in_match_dup.
2519 This routine is marks all MATCH_OPERANDs inside PATTERN as occupied. */
2521 mark_operands_from_match_dup (rtx pattern
)
2524 int i
, j
, len
, opno
;
2526 if (GET_CODE (pattern
) == MATCH_OPERAND
2527 || GET_CODE (pattern
) == MATCH_OPERATOR
2528 || GET_CODE (pattern
) == MATCH_PARALLEL
)
2530 opno
= XINT (pattern
, 0);
2531 gcc_assert (opno
>= 0 && opno
< MAX_OPERANDS
);
2532 used_operands_numbers
[opno
] = 1;
2534 fmt
= GET_RTX_FORMAT (GET_CODE (pattern
));
2535 len
= GET_RTX_LENGTH (GET_CODE (pattern
));
2536 for (i
= 0; i
< len
; i
++)
2541 mark_operands_from_match_dup (XEXP (pattern
, i
));
2544 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
2545 mark_operands_from_match_dup (XVECEXP (pattern
, i
, j
));
2551 /* This is a subroutine of adjust_operands_numbers.
2552 It goes through all expressions in PATTERN and when MATCH_DUP is
2553 met, all MATCH_OPERANDs inside it is marked as occupied. The
2554 process of marking is done by routin mark_operands_from_match_dup. */
2556 mark_operands_used_in_match_dup (rtx pattern
)
2559 int i
, j
, len
, opno
;
2561 if (GET_CODE (pattern
) == MATCH_DUP
)
2563 opno
= XINT (pattern
, 0);
2564 gcc_assert (opno
>= 0 && opno
< MAX_OPERANDS
);
2565 mark_operands_from_match_dup (operand_data
[opno
]);
2568 fmt
= GET_RTX_FORMAT (GET_CODE (pattern
));
2569 len
= GET_RTX_LENGTH (GET_CODE (pattern
));
2570 for (i
= 0; i
< len
; i
++)
2575 mark_operands_used_in_match_dup (XEXP (pattern
, i
));
2578 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
2579 mark_operands_used_in_match_dup (XVECEXP (pattern
, i
, j
));
2585 /* This is subroutine of renumerate_operands_in_pattern.
2586 It finds first not-occupied operand-index. */
2588 find_first_unused_number_of_operand ()
2591 for (i
= 0; i
< MAX_OPERANDS
; i
++)
2592 if (!used_operands_numbers
[i
])
2594 return MAX_OPERANDS
;
2597 /* This is subroutine of adjust_operands_numbers.
2598 It visits all expressions in PATTERN and assigns not-occupied
2599 operand indexes to MATCH_OPERANDs and MATCH_OPERATORs of this
2602 renumerate_operands_in_pattern (rtx pattern
)
2606 int i
, j
, len
, new_opno
;
2607 code
= GET_CODE (pattern
);
2609 if (code
== MATCH_OPERAND
2610 || code
== MATCH_OPERATOR
)
2612 new_opno
= find_first_unused_number_of_operand ();
2613 gcc_assert (new_opno
>= 0 && new_opno
< MAX_OPERANDS
);
2614 XINT (pattern
, 0) = new_opno
;
2615 used_operands_numbers
[new_opno
] = 1;
2618 fmt
= GET_RTX_FORMAT (GET_CODE (pattern
));
2619 len
= GET_RTX_LENGTH (GET_CODE (pattern
));
2620 for (i
= 0; i
< len
; i
++)
2625 renumerate_operands_in_pattern (XEXP (pattern
, i
));
2628 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
2629 renumerate_operands_in_pattern (XVECEXP (pattern
, i
, j
));
2635 /* If output pattern of define_subst contains MATCH_DUP, then this
2636 expression would be replaced with the pattern, matched with
2637 MATCH_OPERAND from input pattern. This pattern could contain any
2638 number of MATCH_OPERANDs, MATCH_OPERATORs etc., so it's possible
2639 that a MATCH_OPERAND from output_pattern (if any) would have the
2640 same number, as MATCH_OPERAND from copied pattern. To avoid such
2641 indexes overlapping, we assign new indexes to MATCH_OPERANDs,
2642 laying in the output pattern outside of MATCH_DUPs. */
2644 adjust_operands_numbers (rtx pattern
)
2646 mark_operands_used_in_match_dup (pattern
);
2648 renumerate_operands_in_pattern (pattern
);
2653 /* Generate RTL expression
2657 generate_match_dup (int opno
)
2659 rtx return_rtx
= rtx_alloc (MATCH_DUP
);
2660 PUT_CODE (return_rtx
, MATCH_DUP
);
2661 XINT (return_rtx
, 0) = opno
;
2665 /* This routine checks all match_operands in PATTERN and if some of
2666 have the same index, it replaces all of them except the first one to
2668 Usually, match_operands with the same indexes are forbidden, but
2669 after define_subst copy an RTL-expression from original template,
2670 indexes of existed and just-copied match_operands could coincide.
2671 To fix it, we replace one of them with match_dup. */
2673 replace_duplicating_operands_in_pattern (rtx pattern
)
2676 int i
, j
, len
, opno
;
2679 if (GET_CODE (pattern
) == MATCH_OPERAND
)
2681 opno
= XINT (pattern
, 0);
2682 gcc_assert (opno
>= 0 && opno
< MAX_OPERANDS
);
2683 if (match_operand_entries_in_pattern
[opno
] == NULL
)
2685 match_operand_entries_in_pattern
[opno
] = pattern
;
2690 /* Compare predicates before replacing with match_dup. */
2691 if (strcmp (XSTR (pattern
, 1),
2692 XSTR (match_operand_entries_in_pattern
[opno
], 1)))
2694 error ("duplicated match_operands with different predicates were"
2698 return generate_match_dup (opno
);
2701 fmt
= GET_RTX_FORMAT (GET_CODE (pattern
));
2702 len
= GET_RTX_LENGTH (GET_CODE (pattern
));
2703 for (i
= 0; i
< len
; i
++)
2708 mdup
= replace_duplicating_operands_in_pattern (XEXP (pattern
, i
));
2710 XEXP (pattern
, i
) = mdup
;
2713 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
2716 replace_duplicating_operands_in_pattern (XVECEXP
2719 XVECEXP (pattern
, i
, j
) = mdup
;
2727 /* The routine modifies given input PATTERN of define_subst, replacing
2728 MATCH_DUP and MATCH_OP_DUP with operands from define_insn original
2729 pattern, whose operands are stored in OPERAND_DATA array.
2730 It also duplicates constraints in operands - constraints from
2731 define_insn operands are duplicated N_SUBST_ALT times, constraints
2732 from define_subst operands are duplicated N_ALT times.
2733 After the duplication, returned output rtl-pattern contains every
2734 combination of input constraints Vs constraints from define_subst
2737 subst_dup (rtx pattern
, int n_alt
, int n_subst_alt
)
2741 int i
, j
, len
, opno
;
2743 code
= GET_CODE (pattern
);
2748 opno
= XINT (pattern
, 0);
2750 gcc_assert (opno
>= 0 && opno
< MAX_OPERANDS
);
2752 if (operand_data
[opno
])
2754 pattern
= copy_rtx (operand_data
[opno
]);
2756 /* Duplicate constraints. */
2757 pattern
= alter_constraints (pattern
, n_subst_alt
,
2758 duplicate_alternatives
);
2766 fmt
= GET_RTX_FORMAT (GET_CODE (pattern
));
2767 len
= GET_RTX_LENGTH (GET_CODE (pattern
));
2768 for (i
= 0; i
< len
; i
++)
2773 if (code
!= MATCH_DUP
&& code
!= MATCH_OP_DUP
)
2774 XEXP (pattern
, i
) = subst_dup (XEXP (pattern
, i
),
2775 n_alt
, n_subst_alt
);
2778 if (XVEC (pattern
, i
) == NULL
)
2782 if (code
!= MATCH_DUP
&& code
!= MATCH_OP_DUP
)
2783 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
2784 XVECEXP (pattern
, i
, j
) = subst_dup (XVECEXP (pattern
, i
, j
),
2785 n_alt
, n_subst_alt
);
2788 case 'r': case 'p': case 'i': case 'w':
2789 case '0': case 's': case 'S': case 'T':
2800 /* If we have any DEFINE_COND_EXEC patterns, expand the DEFINE_INSN
2801 patterns appropriately. */
2804 process_define_cond_exec (void)
2806 class queue_elem
*elem
;
2808 identify_predicable_attribute ();
2812 for (elem
= define_cond_exec_queue
; elem
; elem
= elem
->next
)
2813 process_one_cond_exec (elem
);
2816 /* If we have any DEFINE_SUBST patterns, expand DEFINE_INSN and
2817 DEFINE_EXPAND patterns appropriately. */
2820 process_define_subst (void)
2822 class queue_elem
*elem
, *elem_attr
;
2824 /* Check if each define_subst has corresponding define_subst_attr. */
2825 for (elem
= define_subst_queue
; elem
; elem
= elem
->next
)
2827 for (elem_attr
= define_subst_attr_queue
;
2829 elem_attr
= elem_attr
->next
)
2830 if (strcmp (XSTR (elem
->data
, 0), XSTR (elem_attr
->data
, 1)) == 0)
2833 error_at (elem
->loc
,
2834 "%s: `define_subst' must have at least one "
2835 "corresponding `define_subst_attr'",
2836 XSTR (elem
->data
, 0));
2843 for (elem
= define_insn_queue
; elem
; elem
= elem
->next
)
2844 process_substs_on_one_elem (elem
, define_insn_queue
);
2845 for (elem
= other_queue
; elem
; elem
= elem
->next
)
2847 if (GET_CODE (elem
->data
) != DEFINE_EXPAND
)
2849 process_substs_on_one_elem (elem
, other_queue
);
2853 /* A subclass of rtx_reader which reads .md files and calls process_rtx on
2854 the top-level elements. */
2856 class gen_reader
: public rtx_reader
2859 gen_reader () : rtx_reader (false) {}
2860 void handle_unknown_directive (file_location
, const char *) final override
;
2864 gen_reader::handle_unknown_directive (file_location loc
, const char *rtx_name
)
2866 auto_vec
<rtx
, 32> subrtxs
;
2867 if (!read_rtx (rtx_name
, &subrtxs
))
2872 FOR_EACH_VEC_ELT (subrtxs
, i
, x
)
2873 process_rtx (x
, loc
);
2876 /* Add mnemonic STR with length LEN to the mnemonic hash table
2877 MNEMONIC_HTAB. A trailing zero end character is appended to STR
2878 and a permanent heap copy of STR is created. */
2881 add_mnemonic_string (htab_t mnemonic_htab
, const char *str
, size_t len
)
2885 char *str_zero
= (char*)alloca (len
+ 1);
2887 memcpy (str_zero
, str
, len
);
2888 str_zero
[len
] = '\0';
2890 slot
= htab_find_slot (mnemonic_htab
, str_zero
, INSERT
);
2895 /* Not found; create a permanent copy and add it to the hash table. */
2896 new_str
= XNEWVAR (char, len
+ 1);
2897 memcpy (new_str
, str_zero
, len
+ 1);
2901 /* Scan INSN for mnemonic strings and add them to the mnemonic hash
2902 table in MNEMONIC_HTAB.
2904 The mnemonics cannot be found if they are emitted using C code.
2906 If a mnemonic string contains ';' or a newline the string assumed
2907 to consist of more than a single instruction. The attribute value
2908 will then be set to the user defined default value. */
2911 gen_mnemonic_setattr (htab_t mnemonic_htab
, rtx insn
)
2913 const char *template_code
, *cp
;
2919 struct obstack
*string_obstack
= rtx_reader_ptr
->get_string_obstack ();
2921 template_code
= XTMPL (insn
, 3);
2923 /* Skip patterns which use C code to emit the template. */
2924 if (template_code
[0] == '*')
2927 if (template_code
[0] == '@')
2928 cp
= &template_code
[1];
2930 cp
= &template_code
[0];
2934 const char *ep
, *sp
;
2937 while (ISSPACE (*cp
))
2940 for (ep
= sp
= cp
; !IS_VSPACE (*ep
) && *ep
!= '\0'; ++ep
)
2945 obstack_1grow (string_obstack
, ',');
2947 while (cp
< sp
&& ((*cp
>= '0' && *cp
<= '9')
2948 || (*cp
>= 'a' && *cp
<= 'z')))
2951 obstack_1grow (string_obstack
, *cp
);
2958 if (*cp
== ';' || (*cp
== '\\' && cp
[1] == 'n'))
2960 /* Don't set a value if there are more than one
2961 instruction in the string. */
2962 obstack_blank_fast (string_obstack
, -size
);
2971 obstack_1grow (string_obstack
, '*');
2973 add_mnemonic_string (mnemonic_htab
,
2974 (char *) obstack_next_free (string_obstack
) - size
,
2979 /* An insn definition might emit an empty string. */
2980 if (obstack_object_size (string_obstack
) == 0)
2983 obstack_1grow (string_obstack
, '\0');
2985 set_attr
= rtx_alloc (SET_ATTR
);
2986 XSTR (set_attr
, 1) = XOBFINISH (string_obstack
, char *);
2987 attr_name
= XNEWVAR (char, strlen (MNEMONIC_ATTR_NAME
) + 1);
2988 strcpy (attr_name
, MNEMONIC_ATTR_NAME
);
2989 XSTR (set_attr
, 0) = attr_name
;
2991 if (!XVEC (insn
, 4))
2994 vec_len
= XVECLEN (insn
, 4);
2996 new_vec
= rtvec_alloc (vec_len
+ 1);
2997 for (i
= 0; i
< vec_len
; i
++)
2998 RTVEC_ELT (new_vec
, i
) = XVECEXP (insn
, 4, i
);
2999 RTVEC_ELT (new_vec
, vec_len
) = set_attr
;
3000 XVEC (insn
, 4) = new_vec
;
3003 /* This function is called for the elements in the mnemonic hashtable
3004 and generates a comma separated list of the mnemonics. */
3007 mnemonic_htab_callback (void **slot
, void *info ATTRIBUTE_UNUSED
)
3009 struct obstack
*string_obstack
= rtx_reader_ptr
->get_string_obstack ();
3011 obstack_grow (string_obstack
, (char*) *slot
, strlen ((char*) *slot
));
3012 obstack_1grow (string_obstack
, ',');
3016 /* Generate (set_attr "mnemonic" "..") RTXs and append them to every
3017 insn definition in case the back end requests it by defining the
3018 mnemonic attribute. The values for the attribute will be extracted
3019 from the output patterns of the insn definitions as far as
3023 gen_mnemonic_attr (void)
3025 class queue_elem
*elem
;
3026 rtx mnemonic_attr
= NULL
;
3027 htab_t mnemonic_htab
;
3028 const char *str
, *p
;
3030 struct obstack
*string_obstack
= rtx_reader_ptr
->get_string_obstack ();
3035 /* Look for the DEFINE_ATTR for `mnemonic'. */
3036 for (elem
= define_attr_queue
; elem
!= *define_attr_tail
; elem
= elem
->next
)
3037 if (GET_CODE (elem
->data
) == DEFINE_ATTR
3038 && strcmp (XSTR (elem
->data
, 0), MNEMONIC_ATTR_NAME
) == 0)
3040 mnemonic_attr
= elem
->data
;
3044 /* A (define_attr "mnemonic" "...") indicates that the back-end
3045 wants a mnemonic attribute to be generated. */
3049 mnemonic_htab
= htab_create_alloc (MNEMONIC_HTAB_SIZE
, htab_hash_string
,
3050 htab_eq_string
, 0, xcalloc
, free
);
3052 for (elem
= define_insn_queue
; elem
; elem
= elem
->next
)
3054 rtx insn
= elem
->data
;
3057 /* Check if the insn definition already has
3058 (set_attr "mnemonic" ...) or (set (attr "mnemonic") ...). */
3060 for (i
= 0; i
< XVECLEN (insn
, 4); i
++)
3062 rtx set_attr
= XVECEXP (insn
, 4, i
);
3064 switch (GET_CODE (set_attr
))
3067 case SET_ATTR_ALTERNATIVE
:
3068 if (strcmp (XSTR (set_attr
, 0), MNEMONIC_ATTR_NAME
) == 0)
3072 if (GET_CODE (SET_DEST (set_attr
)) == ATTR
3073 && strcmp (XSTR (SET_DEST (set_attr
), 0),
3074 MNEMONIC_ATTR_NAME
) == 0)
3083 gen_mnemonic_setattr (mnemonic_htab
, insn
);
3086 /* Add the user defined values to the hash table. */
3087 str
= XSTR (mnemonic_attr
, 1);
3088 while ((p
= scan_comma_elt (&str
)) != NULL
)
3089 add_mnemonic_string (mnemonic_htab
, p
, str
- p
);
3091 htab_traverse (mnemonic_htab
, mnemonic_htab_callback
, NULL
);
3093 /* Replace the last ',' with the zero end character. */
3094 *((char *) obstack_next_free (string_obstack
) - 1) = '\0';
3095 XSTR (mnemonic_attr
, 1) = XOBFINISH (string_obstack
, char *);
3098 /* Check if there are DEFINE_ATTRs with the same name. */
3100 check_define_attr_duplicates ()
3102 class queue_elem
*elem
;
3107 attr_htab
= htab_create (500, htab_hash_string
, htab_eq_string
, NULL
);
3109 for (elem
= define_attr_queue
; elem
; elem
= elem
->next
)
3111 attr_name
= xstrdup (XSTR (elem
->data
, 0));
3113 slot
= htab_find_slot (attr_htab
, attr_name
, INSERT
);
3118 error_at (elem
->loc
, "redefinition of attribute '%s'", attr_name
);
3119 htab_delete (attr_htab
);
3126 htab_delete (attr_htab
);
3129 /* The entry point for initializing the reader. */
3132 init_rtx_reader_args_cb (int argc
, const char **argv
,
3133 bool (*parse_opt
) (const char *))
3135 /* Prepare to read input. */
3136 condition_table
= htab_create (500, hash_c_test
, cmp_c_test
, NULL
);
3137 init_predicate_table ();
3138 obstack_init (rtl_obstack
);
3140 /* Start at 1, to make 0 available for CODE_FOR_nothing. */
3141 insn_sequence_num
= 1;
3143 /* These sequences are not used as indices, so can start at 1 also. */
3144 split_sequence_num
= 1;
3145 peephole2_sequence_num
= 1;
3147 gen_reader
*reader
= new gen_reader ();
3148 reader
->read_md_files (argc
, argv
, parse_opt
);
3150 if (define_attr_queue
!= NULL
)
3151 check_define_attr_duplicates ();
3153 /* Process define_cond_exec patterns. */
3154 if (define_cond_exec_queue
!= NULL
)
3155 process_define_cond_exec ();
3157 /* Process define_subst patterns. */
3158 if (define_subst_queue
!= NULL
)
3159 process_define_subst ();
3161 if (define_attr_queue
!= NULL
)
3162 gen_mnemonic_attr ();
3173 /* Programs that don't have their own options can use this entry point
3176 init_rtx_reader_args (int argc
, const char **argv
)
3178 return init_rtx_reader_args_cb (argc
, argv
, 0);
3181 /* Count the number of patterns in all queues and return the count. */
3185 int count
= 0, truth
= 1;
3187 class queue_elem
*cur
= define_attr_queue
;
3192 truth
= maybe_eval_c_test (get_c_test (def
));
3193 if (truth
|| !insn_elision
)
3198 cur
= define_pred_queue
;
3203 truth
= maybe_eval_c_test (get_c_test (def
));
3204 if (truth
|| !insn_elision
)
3209 cur
= define_insn_queue
;
3215 truth
= maybe_eval_c_test (get_c_test (def
));
3216 if (truth
|| !insn_elision
)
3227 truth
= maybe_eval_c_test (get_c_test (def
));
3228 if (truth
|| !insn_elision
)
3236 /* Try to read a single rtx from the file. Return true on success,
3237 describing it in *INFO. */
3240 read_md_rtx (md_rtx_info
*info
)
3242 int truth
, *counter
;
3245 /* Discard insn patterns which we know can never match (because
3246 their C test is provably always false). If insn_elision is
3247 false, our caller needs to see all the patterns. Note that the
3248 elided patterns are never counted by the sequence numbering; it
3249 is the caller's responsibility, when insn_elision is false, not
3250 to use elided pattern numbers for anything. */
3253 class queue_elem
**queue
, *elem
;
3255 /* Read all patterns from a given queue before moving on to the next. */
3256 if (define_attr_queue
!= NULL
)
3257 queue
= &define_attr_queue
;
3258 else if (define_pred_queue
!= NULL
)
3259 queue
= &define_pred_queue
;
3260 else if (define_insn_queue
!= NULL
)
3261 queue
= &define_insn_queue
;
3262 else if (other_queue
!= NULL
)
3263 queue
= &other_queue
;
3268 *queue
= elem
->next
;
3271 info
->loc
= elem
->loc
;
3274 truth
= maybe_eval_c_test (get_c_test (def
));
3276 while (truth
== 0 && insn_elision
);
3278 /* Perform code-specific processing and pick the appropriate sequence
3280 switch (GET_CODE (def
))
3284 /* insn_sequence_num is used here so the name table will match caller's
3285 idea of insn numbering, whether or not elision is active. */
3286 record_insn_name (insn_sequence_num
, XSTR (def
, 0));
3289 case DEFINE_PEEPHOLE
:
3290 counter
= &insn_sequence_num
;
3294 counter
= &split_sequence_num
;
3297 case DEFINE_PEEPHOLE2
:
3298 counter
= &peephole2_sequence_num
;
3308 info
->index
= *counter
;
3316 rtx_locs
= new hash_map
<rtx
, file_location
>;
3317 rtx_locs
->put (info
->def
, info
->loc
);
3322 /* Return the file location of DEFINE_* rtx X, which was previously
3323 returned by read_md_rtx. */
3325 get_file_location (rtx x
)
3327 gcc_assert (rtx_locs
);
3328 file_location
*entry
= rtx_locs
->get (x
);
3333 /* Return the number of possible INSN_CODEs. Only meaningful once the
3334 whole file has been processed. */
3336 get_num_insn_codes ()
3338 return insn_sequence_num
;
3341 /* Return the C test that says whether definition rtx DEF can be used,
3342 or "" if it can be used unconditionally. */
3347 switch (GET_CODE (x
))
3355 case DEFINE_PEEPHOLE
:
3356 case DEFINE_PEEPHOLE2
:
3364 /* Helper functions for insn elision. */
3366 /* Compute a hash function of a c_test structure, which is keyed
3367 by its ->expr field. */
3369 hash_c_test (const void *x
)
3371 const struct c_test
*a
= (const struct c_test
*) x
;
3372 const unsigned char *base
, *s
= (const unsigned char *) a
->expr
;
3380 while ((c
= *s
++) != '\0')
3382 hash
+= c
+ (c
<< 17);
3387 hash
+= len
+ (len
<< 17);
3393 /* Compare two c_test expression structures. */
3395 cmp_c_test (const void *x
, const void *y
)
3397 const struct c_test
*a
= (const struct c_test
*) x
;
3398 const struct c_test
*b
= (const struct c_test
*) y
;
3400 return !strcmp (a
->expr
, b
->expr
);
3403 /* Given a string representing a C test expression, look it up in the
3404 condition_table and report whether or not its value is known
3405 at compile time. Returns a tristate: 1 for known true, 0 for
3406 known false, -1 for unknown. */
3408 maybe_eval_c_test (const char *expr
)
3410 const struct c_test
*test
;
3411 struct c_test dummy
;
3417 test
= (const struct c_test
*)htab_find (condition_table
, &dummy
);
3423 /* Record the C test expression EXPR in the condition_table, with
3424 value VAL. Duplicates clobber previous entries. */
3427 add_c_test (const char *expr
, int value
)
3429 struct c_test
*test
;
3434 test
= XNEW (struct c_test
);
3436 test
->value
= value
;
3438 *(htab_find_slot (condition_table
, test
, INSERT
)) = test
;
3441 /* For every C test, call CALLBACK with two arguments: a pointer to
3442 the condition structure and INFO. Stops when CALLBACK returns zero. */
3444 traverse_c_tests (htab_trav callback
, void *info
)
3446 if (condition_table
)
3447 htab_traverse (condition_table
, callback
, info
);
3450 /* Helper functions for define_predicate and define_special_predicate
3451 processing. Shared between genrecog.cc and genpreds.cc. */
3453 static htab_t predicate_table
;
3454 struct pred_data
*first_predicate
;
3455 static struct pred_data
**last_predicate
= &first_predicate
;
3458 hash_struct_pred_data (const void *ptr
)
3460 return htab_hash_string (((const struct pred_data
*)ptr
)->name
);
3464 eq_struct_pred_data (const void *a
, const void *b
)
3466 return !strcmp (((const struct pred_data
*)a
)->name
,
3467 ((const struct pred_data
*)b
)->name
);
3471 lookup_predicate (const char *name
)
3473 struct pred_data key
;
3475 return (struct pred_data
*) htab_find (predicate_table
, &key
);
3478 /* Record that predicate PRED can accept CODE. */
3481 add_predicate_code (struct pred_data
*pred
, enum rtx_code code
)
3483 if (!pred
->codes
[code
])
3486 pred
->codes
[code
] = true;
3488 if (GET_RTX_CLASS (code
) != RTX_CONST_OBJ
)
3489 pred
->allows_non_const
= true;
3496 && code
!= STRICT_LOW_PART
3497 && code
!= ZERO_EXTRACT
3499 pred
->allows_non_lvalue
= true;
3501 if (pred
->num_codes
== 1)
3502 pred
->singleton
= code
;
3503 else if (pred
->num_codes
== 2)
3504 pred
->singleton
= UNKNOWN
;
3509 add_predicate (struct pred_data
*pred
)
3511 void **slot
= htab_find_slot (predicate_table
, pred
, INSERT
);
3514 error ("duplicate predicate definition for '%s'", pred
->name
);
3518 *last_predicate
= pred
;
3519 last_predicate
= &pred
->next
;
3522 /* This array gives the initial content of the predicate table. It
3523 has entries for all predicates defined in recog.cc. */
3525 struct std_pred_table
3529 bool allows_const_p
;
3530 RTX_CODE codes
[NUM_RTX_CODE
];
3533 static const struct std_pred_table std_preds
[] = {
3534 {"general_operand", false, true, {SUBREG
, REG
, MEM
}},
3535 {"address_operand", true, true, {SUBREG
, REG
, MEM
, PLUS
, MINUS
, MULT
,
3536 ZERO_EXTEND
, SIGN_EXTEND
, AND
}},
3537 {"register_operand", false, false, {SUBREG
, REG
}},
3538 {"pmode_register_operand", true, false, {SUBREG
, REG
}},
3539 {"scratch_operand", false, false, {SCRATCH
, REG
}},
3540 {"immediate_operand", false, true, {UNKNOWN
}},
3541 {"const_int_operand", false, false, {CONST_INT
}},
3542 #if TARGET_SUPPORTS_WIDE_INT
3543 {"const_scalar_int_operand", false, false, {CONST_INT
, CONST_WIDE_INT
}},
3544 {"const_double_operand", false, false, {CONST_DOUBLE
}},
3546 {"const_double_operand", false, false, {CONST_INT
, CONST_DOUBLE
}},
3548 {"nonimmediate_operand", false, false, {SUBREG
, REG
, MEM
}},
3549 {"nonmemory_operand", false, true, {SUBREG
, REG
}},
3550 {"push_operand", false, false, {MEM
}},
3551 {"pop_operand", false, false, {MEM
}},
3552 {"memory_operand", false, false, {SUBREG
, MEM
}},
3553 {"indirect_operand", false, false, {SUBREG
, MEM
}},
3554 {"ordered_comparison_operator", false, false, {EQ
, NE
,
3556 LEU
, LTU
, GEU
, GTU
}},
3557 {"comparison_operator", false, false, {EQ
, NE
,
3564 #define NUM_KNOWN_STD_PREDS ARRAY_SIZE (std_preds)
3566 /* Initialize the table of predicate definitions, starting with
3567 the information we have on generic predicates. */
3570 init_predicate_table (void)
3573 struct pred_data
*pred
;
3575 predicate_table
= htab_create_alloc (37, hash_struct_pred_data
,
3576 eq_struct_pred_data
, 0,
3579 for (i
= 0; i
< NUM_KNOWN_STD_PREDS
; i
++)
3581 pred
= XCNEW (struct pred_data
);
3582 pred
->name
= std_preds
[i
].name
;
3583 pred
->special
= std_preds
[i
].special
;
3585 for (j
= 0; std_preds
[i
].codes
[j
] != 0; j
++)
3586 add_predicate_code (pred
, std_preds
[i
].codes
[j
]);
3588 if (std_preds
[i
].allows_const_p
)
3589 for (j
= 0; j
< NUM_RTX_CODE
; j
++)
3590 if (GET_RTX_CLASS (j
) == RTX_CONST_OBJ
)
3591 add_predicate_code (pred
, (enum rtx_code
) j
);
3593 add_predicate (pred
);
3597 /* These functions allow linkage with print-rtl.cc. Also, some generators
3598 like to annotate their output with insn names. */
3600 /* Holds an array of names indexed by insn_code_number. */
3601 static char **insn_name_ptr
= 0;
3602 static int insn_name_ptr_size
= 0;
3605 get_insn_name (int code
)
3607 if (code
< insn_name_ptr_size
)
3608 return insn_name_ptr
[code
];
3614 record_insn_name (int code
, const char *name
)
3616 static const char *last_real_name
= "insn";
3617 static int last_real_code
= 0;
3620 if (insn_name_ptr_size
<= code
)
3623 new_size
= (insn_name_ptr_size
? insn_name_ptr_size
* 2 : 512);
3624 insn_name_ptr
= XRESIZEVEC (char *, insn_name_ptr
, new_size
);
3625 memset (insn_name_ptr
+ insn_name_ptr_size
, 0,
3626 sizeof (char *) * (new_size
- insn_name_ptr_size
));
3627 insn_name_ptr_size
= new_size
;
3630 if (!name
|| name
[0] == '\0')
3632 new_name
= XNEWVAR (char, strlen (last_real_name
) + 10);
3633 sprintf (new_name
, "%s+%d", last_real_name
, code
- last_real_code
);
3637 last_real_name
= new_name
= xstrdup (name
);
3638 last_real_code
= code
;
3641 insn_name_ptr
[code
] = new_name
;
3644 /* Make STATS describe the operands that appear in rtx X. */
3647 get_pattern_stats_1 (struct pattern_stats
*stats
, rtx x
)
3657 code
= GET_CODE (x
);
3661 case MATCH_OPERATOR
:
3662 case MATCH_PARALLEL
:
3663 stats
->max_opno
= MAX (stats
->max_opno
, XINT (x
, 0));
3670 stats
->max_dup_opno
= MAX (stats
->max_dup_opno
, XINT (x
, 0));
3674 if (stats
->min_scratch_opno
== -1)
3675 stats
->min_scratch_opno
= XINT (x
, 0);
3677 stats
->min_scratch_opno
= MIN (stats
->min_scratch_opno
, XINT (x
, 0));
3678 stats
->max_scratch_opno
= MAX (stats
->max_scratch_opno
, XINT (x
, 0));
3685 fmt
= GET_RTX_FORMAT (code
);
3686 len
= GET_RTX_LENGTH (code
);
3687 for (i
= 0; i
< len
; i
++)
3689 if (fmt
[i
] == 'e' || fmt
[i
] == 'u')
3690 get_pattern_stats_1 (stats
, XEXP (x
, i
));
3691 else if (fmt
[i
] == 'E')
3694 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
3695 get_pattern_stats_1 (stats
, XVECEXP (x
, i
, j
));
3700 /* Make STATS describe the operands that appear in instruction pattern
3704 get_pattern_stats (struct pattern_stats
*stats
, rtvec pattern
)
3708 stats
->max_opno
= -1;
3709 stats
->max_dup_opno
= -1;
3710 stats
->min_scratch_opno
= -1;
3711 stats
->max_scratch_opno
= -1;
3712 stats
->num_dups
= 0;
3714 len
= GET_NUM_ELEM (pattern
);
3715 for (i
= 0; i
< len
; i
++)
3716 get_pattern_stats_1 (stats
, RTVEC_ELT (pattern
, i
));
3718 stats
->num_generator_args
= stats
->max_opno
+ 1;
3719 stats
->num_insn_operands
= MAX (stats
->max_opno
,
3720 stats
->max_scratch_opno
) + 1;
3721 stats
->num_operand_vars
= MAX (stats
->max_opno
,
3722 MAX (stats
->max_dup_opno
,
3723 stats
->max_scratch_opno
)) + 1;
3726 /* Return the emit_* function that should be used for pattern X, or NULL
3727 if we can't pick a particular type at compile time and should instead
3728 fall back to "emit". */
3731 get_emit_function (rtx x
)
3733 switch (classify_insn (x
))
3739 return "emit_call_insn";
3742 return "emit_jump_insn";
3752 /* Return true if we must emit a barrier after pattern X. */
3755 needs_barrier_p (rtx x
)
3757 return (GET_CODE (x
) == SET
3758 && GET_CODE (SET_DEST (x
)) == PC
3759 && GET_CODE (SET_SRC (x
)) == LABEL_REF
);
3764 #define OPTAB_CL(o, p, c, b, l) { #o, p, #b, ZS, #l, o, c, UNKNOWN, 1 },
3765 #define OPTAB_CX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 1 },
3766 #define OPTAB_CD(o, p) { #o, p, NS, ZS, NS, o, UNKNOWN, UNKNOWN, 2 },
3767 #define OPTAB_NL(o, p, c, b, s, l) { #o, p, #b, #s, #l, o, c, c, 3 },
3768 #define OPTAB_NC(o, p, c) { #o, p, NS, ZS, NS, o, c, c, 3 },
3769 #define OPTAB_NX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 3 },
3770 #define OPTAB_VL(o, p, c, b, s, l) { #o, p, #b, #s, #l, o, c, UNKNOWN, 3 },
3771 #define OPTAB_VC(o, p, c) { #o, p, NS, ZS, NS, o, c, UNKNOWN, 3 },
3772 #define OPTAB_VX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 3 },
3773 #define OPTAB_DC(o, p, c) { #o, p, NS, ZS, NS, o, c, c, 4 },
3774 #define OPTAB_D(o, p) { #o, p, NS, ZS, NS, o, UNKNOWN, UNKNOWN, 4 },
3776 /* An array of all optabs. Note that the same optab can appear more
3777 than once, with a different pattern. */
3778 optab_def optabs
[] = {
3779 { "unknown_optab", NULL
, NS
, ZS
, NS
, unknown_optab
, UNKNOWN
, UNKNOWN
, 0 },
3780 #include "optabs.def"
3783 /* The number of entries in optabs[]. */
3784 unsigned int num_optabs
= ARRAY_SIZE (optabs
);
3798 /* Return true if instruction NAME matches pattern PAT, storing information
3799 about the match in P if so. */
3802 match_pattern (optab_pattern
*p
, const char *name
, const char *pat
)
3804 bool force_float
= false;
3805 bool force_int
= false;
3806 bool force_partial_int
= false;
3807 bool force_fixed
= false;
3815 if (*pat
!= *name
++)
3827 force_partial_int
= 1;
3841 /* This loop will stop at the first prefix match, so
3842 look through the modes in reverse order, in case
3843 there are extra CC modes and CC is a prefix of the
3844 CC modes (as it should be). */
3845 for (i
= (MAX_MACHINE_MODE
) - 1; i
>= 0; i
--)
3848 for (p
= GET_MODE_NAME (i
), q
= name
; *p
; p
++, q
++)
3849 if (TOLOWER (*p
) != *q
)
3852 && (! force_int
|| mode_class
[i
] == MODE_INT
3853 || mode_class
[i
] == MODE_VECTOR_INT
)
3854 && (! force_partial_int
3855 || mode_class
[i
] == MODE_INT
3856 || mode_class
[i
] == MODE_PARTIAL_INT
3857 || mode_class
[i
] == MODE_VECTOR_INT
)
3859 || mode_class
[i
] == MODE_FLOAT
3860 || mode_class
[i
] == MODE_DECIMAL_FLOAT
3861 || mode_class
[i
] == MODE_COMPLEX_FLOAT
3862 || mode_class
[i
] == MODE_VECTOR_FLOAT
)
3864 || mode_class
[i
] == MODE_FRACT
3865 || mode_class
[i
] == MODE_UFRACT
3866 || mode_class
[i
] == MODE_ACCUM
3867 || mode_class
[i
] == MODE_UACCUM
3868 || mode_class
[i
] == MODE_VECTOR_FRACT
3869 || mode_class
[i
] == MODE_VECTOR_UFRACT
3870 || mode_class
[i
] == MODE_VECTOR_ACCUM
3871 || mode_class
[i
] == MODE_VECTOR_UACCUM
))
3877 name
+= strlen (GET_MODE_NAME (i
));
3884 force_partial_int
= false;
3885 force_float
= false;
3886 force_fixed
= false;
3896 /* Return true if NAME is the name of an optab, describing it in P if so. */
3899 find_optab (optab_pattern
*p
, const char *name
)
3901 if (*name
== 0 || *name
== '*')
3904 /* See if NAME matches one of the patterns we have for the optabs
3906 for (unsigned int pindex
= 0; pindex
< ARRAY_SIZE (optabs
); pindex
++)
3909 if (match_pattern (p
, name
, optabs
[pindex
].pattern
))
3912 p
->op
= optabs
[pindex
].op
;
3913 p
->sort_num
= (p
->op
<< 20) | (p
->m2
<< 10) | p
->m1
;
3920 /* Find the file to write into next. We try to evenly distribute the contents
3921 over the different files. */
3923 #define SIZED_BASED_CHUNKS 1
3926 choose_output (const vec
<FILE *> &parts
, unsigned &idx
)
3928 if (parts
.length () == 0)
3930 #ifdef SIZED_BASED_CHUNKS
3931 FILE *shortest
= NULL
;
3934 for (unsigned i
= 0; i
< parts
.length (); i
++)
3936 FILE *part
= parts
[i
];
3937 long len
= ftell (part
);
3938 if (!shortest
|| min
> len
)
3947 static int current_file
;
3948 idx
= current_file
++ % parts
.length ();