1 /* Support routines for the various generation passes.
2 Copyright (C) 2000-2020 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/>. */
22 #include "coretypes.h"
28 #include "gensupport.h"
31 #define MAX_OPERANDS 40
33 static rtx operand_data
[MAX_OPERANDS
];
34 static rtx match_operand_entries_in_pattern
[MAX_OPERANDS
];
35 static char used_operands_numbers
[MAX_OPERANDS
];
38 /* In case some macros used by files we include need it, define this here. */
43 static struct obstack obstack
;
44 struct obstack
*rtl_obstack
= &obstack
;
46 /* Counter for named patterns and INSN_CODEs. */
47 static int insn_sequence_num
;
49 /* Counter for define_splits. */
50 static int split_sequence_num
;
52 /* Counter for define_peephole2s. */
53 static int peephole2_sequence_num
;
55 static int predicable_default
;
56 static const char *predicable_true
;
57 static const char *predicable_false
;
59 static const char *subst_true
= "yes";
60 static const char *subst_false
= "no";
62 static htab_t condition_table
;
64 /* We initially queue all patterns, process the define_insn,
65 define_cond_exec and define_subst patterns, then return
66 them one at a time. */
73 class queue_elem
*next
;
74 /* In a DEFINE_INSN that came from a DEFINE_INSN_AND_SPLIT or
75 DEFINE_INSN_AND_REWRITE, SPLIT points to the generated DEFINE_SPLIT. */
76 class queue_elem
*split
;
79 #define MNEMONIC_ATTR_NAME "mnemonic"
80 #define MNEMONIC_HTAB_SIZE 1024
82 static class queue_elem
*define_attr_queue
;
83 static class queue_elem
**define_attr_tail
= &define_attr_queue
;
84 static class queue_elem
*define_pred_queue
;
85 static class queue_elem
**define_pred_tail
= &define_pred_queue
;
86 static class queue_elem
*define_insn_queue
;
87 static class queue_elem
**define_insn_tail
= &define_insn_queue
;
88 static class queue_elem
*define_cond_exec_queue
;
89 static class queue_elem
**define_cond_exec_tail
= &define_cond_exec_queue
;
90 static class queue_elem
*define_subst_queue
;
91 static class queue_elem
**define_subst_tail
= &define_subst_queue
;
92 static class queue_elem
*other_queue
;
93 static class queue_elem
**other_tail
= &other_queue
;
94 static class queue_elem
*define_subst_attr_queue
;
95 static class queue_elem
**define_subst_attr_tail
= &define_subst_attr_queue
;
97 /* Mapping from DEFINE_* rtxes to their location in the source file. */
98 static hash_map
<rtx
, file_location
> *rtx_locs
;
100 static void remove_constraints (rtx
);
102 static int is_predicable (class queue_elem
*);
103 static void identify_predicable_attribute (void);
104 static int n_alternatives (const char *);
105 static void collect_insn_data (rtx
, int *, int *);
106 static const char *alter_test_for_insn (class queue_elem
*,
108 static char *shift_output_template (char *, const char *, int);
109 static const char *alter_output_for_insn (class queue_elem
*,
112 static void process_one_cond_exec (class queue_elem
*);
113 static void process_define_cond_exec (void);
114 static void init_predicate_table (void);
115 static void record_insn_name (int, const char *);
117 static bool has_subst_attribute (class queue_elem
*, class queue_elem
*);
118 static const char * alter_output_for_subst_insn (rtx
, int);
119 static void alter_attrs_for_subst_insn (class queue_elem
*, int);
120 static void process_substs_on_one_elem (class queue_elem
*,
122 static rtx
subst_dup (rtx
, int, int);
123 static void process_define_subst (void);
125 static const char * duplicate_alternatives (const char *, int);
126 static const char * duplicate_each_alternative (const char * str
, int n_dup
);
128 typedef const char * (*constraints_handler_t
) (const char *, int);
129 static rtx
alter_constraints (rtx
, int, constraints_handler_t
);
130 static rtx
adjust_operands_numbers (rtx
);
131 static rtx
replace_duplicating_operands_in_pattern (rtx
);
133 /* Make a version of gen_rtx_CONST_INT so that GEN_INT can be used in
134 the gensupport programs. */
137 gen_rtx_CONST_INT (machine_mode
ARG_UNUSED (mode
),
140 rtx rt
= rtx_alloc (CONST_INT
);
146 /* Return the rtx pattern specified by the list of rtxes in a
147 define_insn or define_split. */
150 add_implicit_parallel (rtvec vec
)
152 if (GET_NUM_ELEM (vec
) == 1)
153 return RTVEC_ELT (vec
, 0);
156 rtx pattern
= rtx_alloc (PARALLEL
);
157 XVEC (pattern
, 0) = vec
;
162 /* Predicate handling.
164 We construct from the machine description a table mapping each
165 predicate to a list of the rtl codes it can possibly match. The
166 function 'maybe_both_true' uses it to deduce that there are no
167 expressions that can be matches by certain pairs of tree nodes.
168 Also, if a predicate can match only one code, we can hardwire that
169 code into the node testing the predicate.
171 Some predicates are flagged as special. validate_pattern will not
172 warn about modeless match_operand expressions if they have a
173 special predicate. Predicates that allow only constants are also
174 treated as special, for this purpose.
176 validate_pattern will warn about predicates that allow non-lvalues
177 when they appear in destination operands.
179 Calculating the set of rtx codes that can possibly be accepted by a
180 predicate expression EXP requires a three-state logic: any given
181 subexpression may definitively accept a code C (Y), definitively
182 reject a code C (N), or may have an indeterminate effect (I). N
183 and I is N; Y or I is Y; Y and I, N or I are both I. Here are full
194 We represent Y with 1, N with 0, I with 2. If any code is left in
195 an I state by the complete expression, we must assume that that
196 code can be accepted. */
202 #define TRISTATE_AND(a,b) \
203 ((a) == I ? ((b) == N ? N : I) : \
204 (b) == I ? ((a) == N ? N : I) : \
207 #define TRISTATE_OR(a,b) \
208 ((a) == I ? ((b) == Y ? Y : I) : \
209 (b) == I ? ((a) == Y ? Y : I) : \
212 #define TRISTATE_NOT(a) \
213 ((a) == I ? I : !(a))
215 /* 0 means no warning about that code yet, 1 means warned. */
216 static char did_you_mean_codes
[NUM_RTX_CODE
];
218 /* Recursively calculate the set of rtx codes accepted by the
219 predicate expression EXP, writing the result to CODES. LOC is
220 the .md file location of the directive containing EXP. */
223 compute_test_codes (rtx exp
, file_location loc
, char *codes
)
225 char op0_codes
[NUM_RTX_CODE
];
226 char op1_codes
[NUM_RTX_CODE
];
227 char op2_codes
[NUM_RTX_CODE
];
230 switch (GET_CODE (exp
))
233 compute_test_codes (XEXP (exp
, 0), loc
, op0_codes
);
234 compute_test_codes (XEXP (exp
, 1), loc
, op1_codes
);
235 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
236 codes
[i
] = TRISTATE_AND (op0_codes
[i
], op1_codes
[i
]);
240 compute_test_codes (XEXP (exp
, 0), loc
, op0_codes
);
241 compute_test_codes (XEXP (exp
, 1), loc
, op1_codes
);
242 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
243 codes
[i
] = TRISTATE_OR (op0_codes
[i
], op1_codes
[i
]);
246 compute_test_codes (XEXP (exp
, 0), loc
, op0_codes
);
247 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
248 codes
[i
] = TRISTATE_NOT (op0_codes
[i
]);
252 /* a ? b : c accepts the same codes as (a & b) | (!a & c). */
253 compute_test_codes (XEXP (exp
, 0), loc
, op0_codes
);
254 compute_test_codes (XEXP (exp
, 1), loc
, op1_codes
);
255 compute_test_codes (XEXP (exp
, 2), loc
, op2_codes
);
256 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
257 codes
[i
] = TRISTATE_OR (TRISTATE_AND (op0_codes
[i
], op1_codes
[i
]),
258 TRISTATE_AND (TRISTATE_NOT (op0_codes
[i
]),
263 /* MATCH_CODE allows a specified list of codes. However, if it
264 does not apply to the top level of the expression, it does not
265 constrain the set of codes for the top level. */
266 if (XSTR (exp
, 1)[0] != '\0')
268 memset (codes
, Y
, NUM_RTX_CODE
);
272 memset (codes
, N
, NUM_RTX_CODE
);
274 const char *next_code
= XSTR (exp
, 0);
277 if (*next_code
== '\0')
279 error_at (loc
, "empty match_code expression");
283 while ((code
= scan_comma_elt (&next_code
)) != 0)
285 size_t n
= next_code
- code
;
288 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
289 if (!strncmp (code
, GET_RTX_NAME (i
), n
)
290 && GET_RTX_NAME (i
)[n
] == '\0')
298 error_at (loc
, "match_code \"%.*s\" matches nothing",
300 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
301 if (!strncasecmp (code
, GET_RTX_NAME (i
), n
)
302 && GET_RTX_NAME (i
)[n
] == '\0'
303 && !did_you_mean_codes
[i
])
305 did_you_mean_codes
[i
] = 1;
306 message_at (loc
, "(did you mean \"%s\"?)",
315 /* MATCH_OPERAND disallows the set of codes that the named predicate
316 disallows, and is indeterminate for the codes that it does allow. */
318 struct pred_data
*p
= lookup_predicate (XSTR (exp
, 1));
321 error_at (loc
, "reference to unknown predicate '%s'",
325 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
326 codes
[i
] = p
->codes
[i
] ? I
: N
;
332 /* (match_test WHATEVER) is completely indeterminate. */
333 memset (codes
, I
, NUM_RTX_CODE
);
337 error_at (loc
, "'%s' cannot be used in predicates or constraints",
338 GET_RTX_NAME (GET_CODE (exp
)));
339 memset (codes
, I
, NUM_RTX_CODE
);
348 /* Return true if NAME is a valid predicate name. */
351 valid_predicate_name_p (const char *name
)
355 if (!ISALPHA (name
[0]) && name
[0] != '_')
357 for (p
= name
+ 1; *p
; p
++)
358 if (!ISALNUM (*p
) && *p
!= '_')
363 /* Process define_predicate directive DESC, which appears at location LOC.
364 Compute the set of codes that can be matched, and record this as a known
368 process_define_predicate (rtx desc
, file_location loc
)
370 struct pred_data
*pred
;
371 char codes
[NUM_RTX_CODE
];
374 if (!valid_predicate_name_p (XSTR (desc
, 0)))
376 error_at (loc
, "%s: predicate name must be a valid C function name",
381 pred
= XCNEW (struct pred_data
);
382 pred
->name
= XSTR (desc
, 0);
383 pred
->exp
= XEXP (desc
, 1);
384 pred
->c_block
= XSTR (desc
, 2);
385 if (GET_CODE (desc
) == DEFINE_SPECIAL_PREDICATE
)
386 pred
->special
= true;
388 compute_test_codes (XEXP (desc
, 1), loc
, codes
);
390 for (i
= 0; i
< NUM_RTX_CODE
; i
++)
392 add_predicate_code (pred
, (enum rtx_code
) i
);
394 add_predicate (pred
);
400 /* Queue PATTERN on LIST_TAIL. Return the address of the new queue
403 static class queue_elem
*
404 queue_pattern (rtx pattern
, class queue_elem
***list_tail
,
407 class queue_elem
*e
= XNEW (class queue_elem
);
413 *list_tail
= &e
->next
;
417 /* Remove element ELEM from QUEUE. */
419 remove_from_queue (class queue_elem
*elem
, class queue_elem
**queue
)
421 class queue_elem
*prev
, *e
;
423 for (e
= *queue
; e
; e
= e
->next
)
433 prev
->next
= elem
->next
;
438 /* Build a define_attr for an binary attribute with name NAME and
439 possible values "yes" and "no", and queue it. */
441 add_define_attr (const char *name
)
443 class queue_elem
*e
= XNEW (class queue_elem
);
444 rtx t1
= rtx_alloc (DEFINE_ATTR
);
446 XSTR (t1
, 1) = "no,yes";
447 XEXP (t1
, 2) = rtx_alloc (CONST_STRING
);
448 XSTR (XEXP (t1
, 2), 0) = "yes";
450 e
->loc
= file_location ("built-in", -1, -1);
451 e
->next
= define_attr_queue
;
452 define_attr_queue
= e
;
456 /* Recursively remove constraints from an rtx. */
459 remove_constraints (rtx part
)
462 const char *format_ptr
;
467 if (GET_CODE (part
) == MATCH_OPERAND
)
469 else if (GET_CODE (part
) == MATCH_SCRATCH
)
472 format_ptr
= GET_RTX_FORMAT (GET_CODE (part
));
474 for (i
= 0; i
< GET_RTX_LENGTH (GET_CODE (part
)); i
++)
475 switch (*format_ptr
++)
479 remove_constraints (XEXP (part
, i
));
482 if (XVEC (part
, i
) != NULL
)
483 for (j
= 0; j
< XVECLEN (part
, i
); j
++)
484 remove_constraints (XVECEXP (part
, i
, j
));
489 /* Recursively replace MATCH_OPERANDs with MATCH_DUPs and MATCH_OPERATORs
490 with MATCH_OP_DUPs in X. */
493 replace_operands_with_dups (rtx x
)
499 if (GET_CODE (x
) == MATCH_OPERAND
)
501 newx
= rtx_alloc (MATCH_DUP
);
502 XINT (newx
, 0) = XINT (x
, 0);
505 else if (GET_CODE (x
) == MATCH_OPERATOR
)
507 newx
= rtx_alloc (MATCH_OP_DUP
);
508 XINT (newx
, 0) = XINT (x
, 0);
509 XVEC (newx
, 1) = XVEC (x
, 2);
513 newx
= shallow_copy_rtx (x
);
515 const char *format_ptr
= GET_RTX_FORMAT (GET_CODE (x
));
516 for (int i
= 0; i
< GET_RTX_LENGTH (GET_CODE (x
)); i
++)
517 switch (*format_ptr
++)
521 XEXP (newx
, i
) = replace_operands_with_dups (XEXP (x
, i
));
524 if (XVEC (x
, i
) != NULL
)
526 XVEC (newx
, i
) = rtvec_alloc (XVECLEN (x
, i
));
527 for (int j
= 0; j
< XVECLEN (x
, i
); j
++)
529 = replace_operands_with_dups (XVECEXP (x
, i
, j
));
536 /* Convert matching pattern VEC from a DEFINE_INSN_AND_REWRITE into
537 a sequence that should be generated by the splitter. */
540 gen_rewrite_sequence (rtvec vec
)
542 rtvec new_vec
= rtvec_alloc (1);
543 rtx x
= add_implicit_parallel (vec
);
544 RTVEC_ELT (new_vec
, 0) = replace_operands_with_dups (x
);
548 /* Process a top level rtx in some way, queuing as appropriate. */
551 process_rtx (rtx desc
, file_location loc
)
553 switch (GET_CODE (desc
))
556 queue_pattern (desc
, &define_insn_tail
, loc
);
559 case DEFINE_COND_EXEC
:
560 queue_pattern (desc
, &define_cond_exec_tail
, loc
);
564 queue_pattern (desc
, &define_subst_tail
, loc
);
567 case DEFINE_SUBST_ATTR
:
568 queue_pattern (desc
, &define_subst_attr_tail
, loc
);
572 case DEFINE_ENUM_ATTR
:
573 queue_pattern (desc
, &define_attr_tail
, loc
);
576 case DEFINE_PREDICATE
:
577 case DEFINE_SPECIAL_PREDICATE
:
578 process_define_predicate (desc
, loc
);
581 case DEFINE_CONSTRAINT
:
582 case DEFINE_REGISTER_CONSTRAINT
:
583 case DEFINE_MEMORY_CONSTRAINT
:
584 case DEFINE_SPECIAL_MEMORY_CONSTRAINT
:
585 case DEFINE_ADDRESS_CONSTRAINT
:
586 queue_pattern (desc
, &define_pred_tail
, loc
);
589 case DEFINE_INSN_AND_SPLIT
:
590 case DEFINE_INSN_AND_REWRITE
:
592 const char *split_cond
;
596 class queue_elem
*insn_elem
;
597 class queue_elem
*split_elem
;
598 int split_code
= (GET_CODE (desc
) == DEFINE_INSN_AND_REWRITE
? 5 : 6);
600 /* Create a split with values from the insn_and_split. */
601 split
= rtx_alloc (DEFINE_SPLIT
);
603 i
= XVECLEN (desc
, 1);
604 XVEC (split
, 0) = rtvec_alloc (i
);
607 XVECEXP (split
, 0, i
) = copy_rtx (XVECEXP (desc
, 1, i
));
608 remove_constraints (XVECEXP (split
, 0, i
));
611 /* If the split condition starts with "&&", append it to the
612 insn condition to create the new split condition. */
613 split_cond
= XSTR (desc
, 4);
614 if (split_cond
[0] == '&' && split_cond
[1] == '&')
616 rtx_reader_ptr
->copy_md_ptr_loc (split_cond
+ 2, split_cond
);
617 split_cond
= rtx_reader_ptr
->join_c_conditions (XSTR (desc
, 2),
620 else if (GET_CODE (desc
) == DEFINE_INSN_AND_REWRITE
)
621 error_at (loc
, "the rewrite condition must start with `&&'");
622 XSTR (split
, 1) = split_cond
;
623 if (GET_CODE (desc
) == DEFINE_INSN_AND_REWRITE
)
624 XVEC (split
, 2) = gen_rewrite_sequence (XVEC (desc
, 1));
626 XVEC (split
, 2) = XVEC (desc
, 5);
627 XSTR (split
, 3) = XSTR (desc
, split_code
);
629 /* Fix up the DEFINE_INSN. */
630 attr
= XVEC (desc
, split_code
+ 1);
631 PUT_CODE (desc
, DEFINE_INSN
);
632 XVEC (desc
, 4) = attr
;
635 insn_elem
= queue_pattern (desc
, &define_insn_tail
, loc
);
636 split_elem
= queue_pattern (split
, &other_tail
, loc
);
637 insn_elem
->split
= split_elem
;
642 queue_pattern (desc
, &other_tail
, loc
);
647 /* Return true if attribute PREDICABLE is true for ELEM, which holds
651 is_predicable (class queue_elem
*elem
)
653 rtvec vec
= XVEC (elem
->data
, 4);
658 return predicable_default
;
660 for (i
= GET_NUM_ELEM (vec
) - 1; i
>= 0; --i
)
662 rtx sub
= RTVEC_ELT (vec
, i
);
663 switch (GET_CODE (sub
))
666 if (strcmp (XSTR (sub
, 0), "predicable") == 0)
668 value
= XSTR (sub
, 1);
673 case SET_ATTR_ALTERNATIVE
:
674 if (strcmp (XSTR (sub
, 0), "predicable") == 0)
676 error_at (elem
->loc
, "multiple alternatives for `predicable'");
682 if (GET_CODE (SET_DEST (sub
)) != ATTR
683 || strcmp (XSTR (SET_DEST (sub
), 0), "predicable") != 0)
686 if (GET_CODE (sub
) == CONST_STRING
)
688 value
= XSTR (sub
, 0);
692 /* ??? It would be possible to handle this if we really tried.
693 It's not easy though, and I'm not going to bother until it
694 really proves necessary. */
695 error_at (elem
->loc
, "non-constant value for `predicable'");
703 return predicable_default
;
706 /* Find out which value we're looking at. Multiple alternatives means at
707 least one is predicable. */
708 if (strchr (value
, ',') != NULL
)
710 if (strcmp (value
, predicable_true
) == 0)
712 if (strcmp (value
, predicable_false
) == 0)
715 error_at (elem
->loc
, "unknown value `%s' for `predicable' attribute", value
);
719 /* Find attribute SUBST in ELEM and assign NEW_VALUE to it. */
721 change_subst_attribute (class queue_elem
*elem
,
722 class queue_elem
*subst_elem
,
723 const char *new_value
)
725 rtvec attrs_vec
= XVEC (elem
->data
, 4);
726 const char *subst_name
= XSTR (subst_elem
->data
, 0);
732 for (i
= GET_NUM_ELEM (attrs_vec
) - 1; i
>= 0; --i
)
734 rtx cur_attr
= RTVEC_ELT (attrs_vec
, i
);
735 if (GET_CODE (cur_attr
) != SET_ATTR
)
737 if (strcmp (XSTR (cur_attr
, 0), subst_name
) == 0)
739 XSTR (cur_attr
, 1) = new_value
;
745 /* Return true if ELEM has the attribute with the name of DEFINE_SUBST
746 represented by SUBST_ELEM and this attribute has value SUBST_TRUE.
747 DEFINE_SUBST isn't applied to patterns without such attribute. In other
748 words, we suppose the default value of the attribute to be 'no' since it is
749 always generated automatically in read-rtl.c. */
751 has_subst_attribute (class queue_elem
*elem
, class queue_elem
*subst_elem
)
753 rtvec attrs_vec
= XVEC (elem
->data
, 4);
754 const char *value
, *subst_name
= XSTR (subst_elem
->data
, 0);
760 for (i
= GET_NUM_ELEM (attrs_vec
) - 1; i
>= 0; --i
)
762 rtx cur_attr
= RTVEC_ELT (attrs_vec
, i
);
763 switch (GET_CODE (cur_attr
))
766 if (strcmp (XSTR (cur_attr
, 0), subst_name
) == 0)
768 value
= XSTR (cur_attr
, 1);
774 if (GET_CODE (SET_DEST (cur_attr
)) != ATTR
775 || strcmp (XSTR (SET_DEST (cur_attr
), 0), subst_name
) != 0)
777 cur_attr
= SET_SRC (cur_attr
);
778 if (GET_CODE (cur_attr
) == CONST_STRING
)
780 value
= XSTR (cur_attr
, 0);
784 /* Only (set_attr "subst" "yes/no") and
785 (set (attr "subst" (const_string "yes/no")))
786 are currently allowed. */
787 error_at (elem
->loc
, "unsupported value for `%s'", subst_name
);
790 case SET_ATTR_ALTERNATIVE
:
791 if (strcmp (XSTR (cur_attr
, 0), subst_name
) == 0)
793 "%s: `set_attr_alternative' is unsupported by "
794 "`define_subst'", XSTR (elem
->data
, 0));
806 if (strcmp (value
, subst_true
) == 0)
808 if (strcmp (value
, subst_false
) == 0)
811 error_at (elem
->loc
, "unknown value `%s' for `%s' attribute",
816 /* Compare RTL-template of original define_insn X to input RTL-template of
817 define_subst PT. Return 1 if the templates match, 0 otherwise.
818 During the comparison, the routine also fills global_array OPERAND_DATA. */
820 subst_pattern_match (rtx x
, rtx pt
, file_location loc
)
822 RTX_CODE code
, code_pt
;
824 const char *fmt
, *pred_name
;
827 code_pt
= GET_CODE (pt
);
829 if (code_pt
== MATCH_OPERAND
)
831 /* MATCH_DUP, and MATCH_OP_DUP don't have a specified mode, so we
832 always accept them. */
833 if (GET_MODE (pt
) != VOIDmode
&& GET_MODE (x
) != GET_MODE (pt
)
834 && (code
!= MATCH_DUP
&& code
!= MATCH_OP_DUP
))
835 return false; /* Modes don't match. */
837 if (code
== MATCH_OPERAND
)
839 pred_name
= XSTR (pt
, 1);
840 if (pred_name
[0] != 0)
842 const struct pred_data
*pred_pt
= lookup_predicate (pred_name
);
843 if (!pred_pt
|| pred_pt
!= lookup_predicate (XSTR (x
, 1)))
844 return false; /* Predicates don't match. */
848 gcc_assert (XINT (pt
, 0) >= 0 && XINT (pt
, 0) < MAX_OPERANDS
);
849 operand_data
[XINT (pt
, 0)] = x
;
853 if (code_pt
== MATCH_OPERATOR
)
855 int x_vecexp_pos
= -1;
858 if (GET_MODE (pt
) != VOIDmode
&& GET_MODE (x
) != GET_MODE (pt
))
861 /* In case X is also match_operator, compare predicates. */
862 if (code
== MATCH_OPERATOR
)
864 pred_name
= XSTR (pt
, 1);
865 if (pred_name
[0] != 0)
867 const struct pred_data
*pred_pt
= lookup_predicate (pred_name
);
868 if (!pred_pt
|| pred_pt
!= lookup_predicate (XSTR (x
, 1)))
874 MATCH_OPERATOR in input template could match in original template
875 either 1) MATCH_OPERAND, 2) UNSPEC, 3) ordinary operation (like PLUS).
876 In the first case operands are at (XVECEXP (x, 2, j)), in the second
877 - at (XVECEXP (x, 0, j)), in the last one - (XEXP (x, j)).
878 X_VECEXP_POS variable shows, where to look for these operands. */
880 || code
== UNSPEC_VOLATILE
)
882 else if (code
== MATCH_OPERATOR
)
887 /* MATCH_OPERATOR or UNSPEC case. */
888 if (x_vecexp_pos
>= 0)
890 /* Compare operands number in X and PT. */
891 if (XVECLEN (x
, x_vecexp_pos
) != XVECLEN (pt
, 2))
893 for (j
= 0; j
< XVECLEN (pt
, 2); j
++)
894 if (!subst_pattern_match (XVECEXP (x
, x_vecexp_pos
, j
),
895 XVECEXP (pt
, 2, j
), loc
))
899 /* Ordinary operator. */
902 /* Compare operands number in X and PT.
903 We count operands differently for X and PT since we compare
904 an operator (with operands directly in RTX) and MATCH_OPERATOR
905 (that has a vector with operands). */
906 if (GET_RTX_LENGTH (code
) != XVECLEN (pt
, 2))
908 for (j
= 0; j
< XVECLEN (pt
, 2); j
++)
909 if (!subst_pattern_match (XEXP (x
, j
), XVECEXP (pt
, 2, j
), loc
))
913 /* Store the operand to OPERAND_DATA array. */
914 gcc_assert (XINT (pt
, 0) >= 0 && XINT (pt
, 0) < MAX_OPERANDS
);
915 operand_data
[XINT (pt
, 0)] = x
;
919 if (code_pt
== MATCH_PAR_DUP
920 || code_pt
== MATCH_DUP
921 || code_pt
== MATCH_OP_DUP
922 || code_pt
== MATCH_SCRATCH
923 || code_pt
== MATCH_PARALLEL
)
925 /* Currently interface for these constructions isn't defined -
926 probably they aren't needed in input template of define_subst at all.
927 So, for now their usage in define_subst is forbidden. */
928 error_at (loc
, "%s cannot be used in define_subst",
929 GET_RTX_NAME (code_pt
));
932 gcc_assert (code
!= MATCH_PAR_DUP
933 && code_pt
!= MATCH_DUP
934 && code_pt
!= MATCH_OP_DUP
935 && code_pt
!= MATCH_SCRATCH
936 && code_pt
!= MATCH_PARALLEL
937 && code_pt
!= MATCH_OPERAND
938 && code_pt
!= MATCH_OPERATOR
);
939 /* If PT is none of the handled above, then we match only expressions with
940 the same code in X. */
944 fmt
= GET_RTX_FORMAT (code_pt
);
945 len
= GET_RTX_LENGTH (code_pt
);
947 for (i
= 0; i
< len
; i
++)
954 case 'r': case 'p': case 'i': case 'w': case 's':
958 if (!subst_pattern_match (XEXP (x
, i
), XEXP (pt
, i
), loc
))
963 if (XVECLEN (x
, i
) != XVECLEN (pt
, i
))
965 for (j
= 0; j
< XVECLEN (pt
, i
); j
++)
966 if (!subst_pattern_match (XVECEXP (x
, i
, j
),
967 XVECEXP (pt
, i
, j
), loc
))
979 /* Examine the attribute "predicable"; discover its boolean values
983 identify_predicable_attribute (void)
985 class queue_elem
*elem
;
986 char *p_true
, *p_false
;
989 /* Look for the DEFINE_ATTR for `predicable', which must exist. */
990 for (elem
= define_attr_queue
; elem
; elem
= elem
->next
)
991 if (strcmp (XSTR (elem
->data
, 0), "predicable") == 0)
994 error_at (define_cond_exec_queue
->loc
,
995 "attribute `predicable' not defined");
999 value
= XSTR (elem
->data
, 1);
1000 p_false
= xstrdup (value
);
1001 p_true
= strchr (p_false
, ',');
1002 if (p_true
== NULL
|| strchr (++p_true
, ',') != NULL
)
1004 error_at (elem
->loc
, "attribute `predicable' is not a boolean");
1010 predicable_true
= p_true
;
1011 predicable_false
= p_false
;
1013 switch (GET_CODE (XEXP (elem
->data
, 2)))
1016 value
= XSTR (XEXP (elem
->data
, 2), 0);
1020 error_at (elem
->loc
, "attribute `predicable' cannot be const");
1025 error_at (elem
->loc
,
1026 "attribute `predicable' must have a constant default");
1031 if (strcmp (value
, p_true
) == 0)
1032 predicable_default
= 1;
1033 else if (strcmp (value
, p_false
) == 0)
1034 predicable_default
= 0;
1037 error_at (elem
->loc
, "unknown value `%s' for `predicable' attribute",
1043 /* Return the number of alternatives in constraint S. */
1046 n_alternatives (const char *s
)
1057 /* The routine scans rtl PATTERN, find match_operand in it and counts
1058 number of alternatives. If PATTERN contains several match_operands
1059 with different number of alternatives, error is emitted, and the
1060 routine returns 0. If all match_operands in PATTERN have the same
1061 number of alternatives, it's stored in N_ALT, and the routine returns 1.
1062 LOC is the location of PATTERN, for error reporting. */
1064 get_alternatives_number (rtx pattern
, int *n_alt
, file_location loc
)
1073 code
= GET_CODE (pattern
);
1077 i
= n_alternatives (XSTR (pattern
, 2));
1078 /* n_alternatives returns 1 if constraint string is empty -
1079 here we fix it up. */
1080 if (!*(XSTR (pattern
, 2)))
1085 else if (i
&& i
!= *n_alt
)
1087 error_at (loc
, "wrong number of alternatives in operand %d",
1096 fmt
= GET_RTX_FORMAT (code
);
1097 len
= GET_RTX_LENGTH (code
);
1098 for (i
= 0; i
< len
; i
++)
1103 if (!get_alternatives_number (XEXP (pattern
, i
), n_alt
, loc
))
1108 if (XVEC (pattern
, i
) == NULL
)
1113 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
1114 if (!get_alternatives_number (XVECEXP (pattern
, i
, j
), n_alt
, loc
))
1118 case 'r': case 'p': case 'i': case 'w':
1119 case '0': case 's': case 'S': case 'T':
1129 /* Determine how many alternatives there are in INSN, and how many
1133 collect_insn_data (rtx pattern
, int *palt
, int *pmax
)
1139 code
= GET_CODE (pattern
);
1144 i
= n_alternatives (XSTR (pattern
, code
== MATCH_SCRATCH
? 1 : 2));
1145 *palt
= (i
> *palt
? i
: *palt
);
1148 case MATCH_OPERATOR
:
1149 case MATCH_PARALLEL
:
1150 i
= XINT (pattern
, 0);
1159 fmt
= GET_RTX_FORMAT (code
);
1160 len
= GET_RTX_LENGTH (code
);
1161 for (i
= 0; i
< len
; i
++)
1166 collect_insn_data (XEXP (pattern
, i
), palt
, pmax
);
1170 if (XVEC (pattern
, i
) == NULL
)
1174 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
1175 collect_insn_data (XVECEXP (pattern
, i
, j
), palt
, pmax
);
1178 case 'r': case 'p': case 'i': case 'w':
1179 case '0': case 's': case 'S': case 'T':
1189 alter_predicate_for_insn (rtx pattern
, int alt
, int max_op
,
1196 code
= GET_CODE (pattern
);
1201 const char *c
= XSTR (pattern
, 2);
1203 if (n_alternatives (c
) != 1)
1205 error_at (loc
, "too many alternatives for operand %d",
1210 /* Replicate C as needed to fill out ALT alternatives. */
1211 if (c
&& *c
&& alt
> 1)
1213 size_t c_len
= strlen (c
);
1214 size_t len
= alt
* (c_len
+ 1);
1215 char *new_c
= XNEWVEC (char, len
);
1217 memcpy (new_c
, c
, c_len
);
1218 for (i
= 1; i
< alt
; ++i
)
1220 new_c
[i
* (c_len
+ 1) - 1] = ',';
1221 memcpy (&new_c
[i
* (c_len
+ 1)], c
, c_len
);
1223 new_c
[len
- 1] = '\0';
1224 XSTR (pattern
, 2) = new_c
;
1229 case MATCH_OPERATOR
:
1231 case MATCH_PARALLEL
:
1232 XINT (pattern
, 0) += max_op
;
1239 fmt
= GET_RTX_FORMAT (code
);
1240 len
= GET_RTX_LENGTH (code
);
1241 for (i
= 0; i
< len
; i
++)
1248 r
= alter_predicate_for_insn (XEXP (pattern
, i
), alt
, max_op
, loc
);
1254 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
1256 r
= alter_predicate_for_insn (XVECEXP (pattern
, i
, j
),
1263 case 'r': case 'p': case 'i': case 'w': case '0': case 's':
1274 /* Duplicate constraints in PATTERN. If pattern is from original
1275 rtl-template, we need to duplicate each alternative - for that we
1276 need to use duplicate_each_alternative () as a functor ALTER.
1277 If pattern is from output-pattern of define_subst, we need to
1278 duplicate constraints in another way - with duplicate_alternatives ().
1279 N_DUP is multiplication factor. */
1281 alter_constraints (rtx pattern
, int n_dup
, constraints_handler_t alter
)
1287 code
= GET_CODE (pattern
);
1291 XSTR (pattern
, 2) = alter (XSTR (pattern
, 2), n_dup
);
1298 fmt
= GET_RTX_FORMAT (code
);
1299 len
= GET_RTX_LENGTH (code
);
1300 for (i
= 0; i
< len
; i
++)
1307 r
= alter_constraints (XEXP (pattern
, i
), n_dup
, alter
);
1313 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
1315 r
= alter_constraints (XVECEXP (pattern
, i
, j
), n_dup
, alter
);
1321 case 'r': case 'p': case 'i': case 'w': case '0': case 's':
1333 alter_test_for_insn (class queue_elem
*ce_elem
,
1334 class queue_elem
*insn_elem
)
1336 return rtx_reader_ptr
->join_c_conditions (XSTR (ce_elem
->data
, 1),
1337 XSTR (insn_elem
->data
, 2));
1340 /* Modify VAL, which is an attribute expression for the "enabled" attribute,
1341 to take "ce_enabled" into account. Return the new expression. */
1343 modify_attr_enabled_ce (rtx val
)
1347 eq_attr
= rtx_alloc (EQ_ATTR
);
1348 ite
= rtx_alloc (IF_THEN_ELSE
);
1349 str
= rtx_alloc (CONST_STRING
);
1351 XSTR (eq_attr
, 0) = "ce_enabled";
1352 XSTR (eq_attr
, 1) = "yes";
1353 XSTR (str
, 0) = "no";
1354 XEXP (ite
, 0) = eq_attr
;
1355 XEXP (ite
, 1) = val
;
1356 XEXP (ite
, 2) = str
;
1361 /* Alter the attribute vector of INSN, which is a COND_EXEC variant created
1362 from a define_insn pattern. We must modify the "predicable" attribute
1363 to be named "ce_enabled", and also change any "enabled" attribute that's
1364 present so that it takes ce_enabled into account.
1365 We rely on the fact that INSN was created with copy_rtx, and modify data
1369 alter_attrs_for_insn (rtx insn
)
1371 static bool global_changes_made
= false;
1372 rtvec vec
= XVEC (insn
, 4);
1376 int predicable_idx
= -1;
1377 int enabled_idx
= -1;
1383 num_elem
= GET_NUM_ELEM (vec
);
1384 for (i
= num_elem
- 1; i
>= 0; --i
)
1386 rtx sub
= RTVEC_ELT (vec
, i
);
1387 switch (GET_CODE (sub
))
1390 if (strcmp (XSTR (sub
, 0), "predicable") == 0)
1393 XSTR (sub
, 0) = "ce_enabled";
1395 else if (strcmp (XSTR (sub
, 0), "enabled") == 0)
1398 XSTR (sub
, 0) = "nonce_enabled";
1402 case SET_ATTR_ALTERNATIVE
:
1403 if (strcmp (XSTR (sub
, 0), "predicable") == 0)
1404 /* We already give an error elsewhere. */
1406 else if (strcmp (XSTR (sub
, 0), "enabled") == 0)
1409 XSTR (sub
, 0) = "nonce_enabled";
1414 if (GET_CODE (SET_DEST (sub
)) != ATTR
)
1416 if (strcmp (XSTR (SET_DEST (sub
), 0), "predicable") == 0)
1418 sub
= SET_SRC (sub
);
1419 if (GET_CODE (sub
) == CONST_STRING
)
1422 XSTR (sub
, 0) = "ce_enabled";
1425 /* We already give an error elsewhere. */
1429 if (strcmp (XSTR (SET_DEST (sub
), 0), "enabled") == 0)
1432 XSTR (SET_DEST (sub
), 0) = "nonce_enabled";
1440 if (predicable_idx
== -1)
1443 if (!global_changes_made
)
1445 class queue_elem
*elem
;
1447 global_changes_made
= true;
1448 add_define_attr ("ce_enabled");
1449 add_define_attr ("nonce_enabled");
1451 for (elem
= define_attr_queue
; elem
; elem
= elem
->next
)
1452 if (strcmp (XSTR (elem
->data
, 0), "enabled") == 0)
1454 XEXP (elem
->data
, 2)
1455 = modify_attr_enabled_ce (XEXP (elem
->data
, 2));
1458 if (enabled_idx
== -1)
1461 new_vec
= rtvec_alloc (num_elem
+ 1);
1462 for (i
= 0; i
< num_elem
; i
++)
1463 RTVEC_ELT (new_vec
, i
) = RTVEC_ELT (vec
, i
);
1464 val
= rtx_alloc (IF_THEN_ELSE
);
1465 XEXP (val
, 0) = rtx_alloc (EQ_ATTR
);
1466 XEXP (val
, 1) = rtx_alloc (CONST_STRING
);
1467 XEXP (val
, 2) = rtx_alloc (CONST_STRING
);
1468 XSTR (XEXP (val
, 0), 0) = "nonce_enabled";
1469 XSTR (XEXP (val
, 0), 1) = "yes";
1470 XSTR (XEXP (val
, 1), 0) = "yes";
1471 XSTR (XEXP (val
, 2), 0) = "no";
1472 set
= rtx_alloc (SET
);
1473 SET_DEST (set
) = rtx_alloc (ATTR
);
1474 XSTR (SET_DEST (set
), 0) = "enabled";
1475 SET_SRC (set
) = modify_attr_enabled_ce (val
);
1476 RTVEC_ELT (new_vec
, i
) = set
;
1477 XVEC (insn
, 4) = new_vec
;
1480 /* As number of constraints is changed after define_subst, we need to
1481 process attributes as well - we need to duplicate them the same way
1482 that we duplicated constraints in original pattern
1483 ELEM is a queue element, containing our rtl-template,
1484 N_DUP - multiplication factor. */
1486 alter_attrs_for_subst_insn (class queue_elem
* elem
, int n_dup
)
1488 rtvec vec
= XVEC (elem
->data
, 4);
1492 if (n_dup
< 2 || ! vec
)
1495 num_elem
= GET_NUM_ELEM (vec
);
1496 for (i
= num_elem
- 1; i
>= 0; --i
)
1498 rtx sub
= RTVEC_ELT (vec
, i
);
1499 switch (GET_CODE (sub
))
1502 if (strchr (XSTR (sub
, 1), ',') != NULL
)
1503 XSTR (sub
, 1) = duplicate_alternatives (XSTR (sub
, 1), n_dup
);
1506 case SET_ATTR_ALTERNATIVE
:
1508 error_at (elem
->loc
,
1509 "%s: `define_subst' does not support attributes "
1510 "assigned by `set' and `set_attr_alternative'",
1511 XSTR (elem
->data
, 0));
1520 /* Adjust all of the operand numbers in SRC to match the shift they'll
1521 get from an operand displacement of DISP. Return a pointer after the
1525 shift_output_template (char *dest
, const char *src
, int disp
)
1534 if (ISDIGIT ((unsigned char) c
))
1536 else if (ISALPHA (c
))
1549 alter_output_for_insn (class queue_elem
*ce_elem
,
1550 class queue_elem
*insn_elem
,
1551 int alt
, int max_op
)
1553 const char *ce_out
, *insn_out
;
1555 size_t len
, ce_len
, insn_len
;
1557 /* ??? Could coordinate with genoutput to not duplicate code here. */
1559 ce_out
= XSTR (ce_elem
->data
, 2);
1560 insn_out
= XTMPL (insn_elem
->data
, 3);
1561 if (!ce_out
|| *ce_out
== '\0')
1564 ce_len
= strlen (ce_out
);
1565 insn_len
= strlen (insn_out
);
1567 if (*insn_out
== '*')
1568 /* You must take care of the predicate yourself. */
1571 if (*insn_out
== '@')
1573 len
= (ce_len
+ 1) * alt
+ insn_len
+ 1;
1574 p
= result
= XNEWVEC (char, len
);
1580 while (ISSPACE ((unsigned char) *insn_out
));
1582 if (*insn_out
!= '#')
1584 p
= shift_output_template (p
, ce_out
, max_op
);
1590 while (*insn_out
&& *insn_out
!= '\n');
1597 len
= ce_len
+ 1 + insn_len
+ 1;
1598 result
= XNEWVEC (char, len
);
1600 p
= shift_output_template (result
, ce_out
, max_op
);
1602 memcpy (p
, insn_out
, insn_len
+ 1);
1608 /* From string STR "a,b,c" produce "a,b,c,a,b,c,a,b,c", i.e. original
1609 string, duplicated N_DUP times. */
1612 duplicate_alternatives (const char * str
, int n_dup
)
1614 int i
, len
, new_len
;
1621 while (ISSPACE (*str
))
1629 new_len
= (len
+ 1) * n_dup
;
1631 sp
= result
= XNEWVEC (char, new_len
);
1633 /* Global modifier characters mustn't be duplicated: skip if found. */
1634 if (*cp
== '=' || *cp
== '+' || *cp
== '%')
1640 /* Copy original constraints N_DUP times. */
1641 for (i
= 0; i
< n_dup
; i
++, sp
+= len
+1)
1643 memcpy (sp
, cp
, len
);
1644 *(sp
+len
) = (i
== n_dup
- 1) ? '\0' : ',';
1650 /* From string STR "a,b,c" produce "a,a,a,b,b,b,c,c,c", i.e. string where
1651 each alternative from the original string is duplicated N_DUP times. */
1653 duplicate_each_alternative (const char * str
, int n_dup
)
1655 int i
, len
, new_len
;
1656 char *result
, *sp
, *ep
, *cp
;
1661 while (ISSPACE (*str
))
1669 new_len
= (strlen (cp
) + 1) * n_dup
;
1671 sp
= result
= XNEWVEC (char, new_len
);
1673 /* Global modifier characters mustn't be duplicated: skip if found. */
1674 if (*cp
== '=' || *cp
== '+' || *cp
== '%')
1679 if ((ep
= strchr (cp
, ',')) != NULL
)
1683 /* Copy a constraint N_DUP times. */
1684 for (i
= 0; i
< n_dup
; i
++, sp
+= len
+ 1)
1686 memcpy (sp
, cp
, len
);
1687 *(sp
+len
) = (ep
== NULL
&& i
== n_dup
- 1) ? '\0' : ',';
1697 /* Alter the output of INSN whose pattern was modified by
1698 DEFINE_SUBST. We must replicate output strings according
1699 to the new number of alternatives ALT in substituted pattern.
1700 If ALT equals 1, output has one alternative or defined by C
1701 code, then output is returned without any changes. */
1704 alter_output_for_subst_insn (rtx insn
, int alt
)
1706 const char *insn_out
, *old_out
;
1708 size_t old_len
, new_len
;
1711 insn_out
= XTMPL (insn
, 3);
1713 if (alt
< 2 || *insn_out
!= '@')
1716 old_out
= insn_out
+ 1;
1717 while (ISSPACE (*old_out
))
1719 old_len
= strlen (old_out
);
1721 new_len
= alt
* (old_len
+ 1) + 1;
1723 new_out
= XNEWVEC (char, new_len
);
1726 for (j
= 0, cp
= new_out
+ 1; j
< alt
; j
++, cp
+= old_len
+ 1)
1728 memcpy (cp
, old_out
, old_len
);
1729 cp
[old_len
] = (j
== alt
- 1) ? '\0' : '\n';
1735 /* Replicate insns as appropriate for the given DEFINE_COND_EXEC. */
1738 process_one_cond_exec (class queue_elem
*ce_elem
)
1740 class queue_elem
*insn_elem
;
1741 for (insn_elem
= define_insn_queue
; insn_elem
; insn_elem
= insn_elem
->next
)
1743 int alternatives
, max_operand
;
1744 rtx pred
, insn
, pattern
, split
;
1748 if (! is_predicable (insn_elem
))
1753 collect_insn_data (insn_elem
->data
, &alternatives
, &max_operand
);
1756 if (XVECLEN (ce_elem
->data
, 0) != 1)
1758 error_at (ce_elem
->loc
, "too many patterns in predicate");
1762 pred
= copy_rtx (XVECEXP (ce_elem
->data
, 0, 0));
1763 pred
= alter_predicate_for_insn (pred
, alternatives
, max_operand
,
1768 /* Construct a new pattern for the new insn. */
1769 insn
= copy_rtx (insn_elem
->data
);
1770 new_name
= XNEWVAR (char, strlen
XSTR (insn_elem
->data
, 0) + 4);
1771 sprintf (new_name
, "*p %s", XSTR (insn_elem
->data
, 0));
1772 XSTR (insn
, 0) = new_name
;
1773 pattern
= rtx_alloc (COND_EXEC
);
1774 XEXP (pattern
, 0) = pred
;
1775 XEXP (pattern
, 1) = add_implicit_parallel (XVEC (insn
, 1));
1776 XVEC (insn
, 1) = rtvec_alloc (1);
1777 XVECEXP (insn
, 1, 0) = pattern
;
1779 if (XVEC (ce_elem
->data
, 3) != NULL
)
1781 rtvec attributes
= rtvec_alloc (XVECLEN (insn
, 4)
1782 + XVECLEN (ce_elem
->data
, 3));
1785 for (i
= 0; i
< XVECLEN (insn
, 4); i
++)
1786 RTVEC_ELT (attributes
, i
) = XVECEXP (insn
, 4, i
);
1788 for (j
= 0; j
< XVECLEN (ce_elem
->data
, 3); j
++, i
++)
1789 RTVEC_ELT (attributes
, i
) = XVECEXP (ce_elem
->data
, 3, j
);
1791 XVEC (insn
, 4) = attributes
;
1794 XSTR (insn
, 2) = alter_test_for_insn (ce_elem
, insn_elem
);
1795 XTMPL (insn
, 3) = alter_output_for_insn (ce_elem
, insn_elem
,
1796 alternatives
, max_operand
);
1797 alter_attrs_for_insn (insn
);
1799 /* Put the new pattern on the `other' list so that it
1800 (a) is not reprocessed by other define_cond_exec patterns
1801 (b) appears after all normal define_insn patterns.
1803 ??? B is debatable. If one has normal insns that match
1804 cond_exec patterns, they will be preferred over these
1805 generated patterns. Whether this matters in practice, or if
1806 it's a good thing, or whether we should thread these new
1807 patterns into the define_insn chain just after their generator
1808 is something we'll have to experiment with. */
1810 queue_pattern (insn
, &other_tail
, insn_elem
->loc
);
1812 if (!insn_elem
->split
)
1815 /* If the original insn came from a define_insn_and_split,
1816 generate a new split to handle the predicated insn. */
1817 split
= copy_rtx (insn_elem
->split
->data
);
1818 /* Predicate the pattern matched by the split. */
1819 pattern
= rtx_alloc (COND_EXEC
);
1820 XEXP (pattern
, 0) = pred
;
1821 XEXP (pattern
, 1) = add_implicit_parallel (XVEC (split
, 0));
1822 XVEC (split
, 0) = rtvec_alloc (1);
1823 XVECEXP (split
, 0, 0) = pattern
;
1825 /* Predicate all of the insns generated by the split. */
1826 for (i
= 0; i
< XVECLEN (split
, 2); i
++)
1828 pattern
= rtx_alloc (COND_EXEC
);
1829 XEXP (pattern
, 0) = pred
;
1830 XEXP (pattern
, 1) = XVECEXP (split
, 2, i
);
1831 XVECEXP (split
, 2, i
) = pattern
;
1833 /* Add the new split to the queue. */
1834 queue_pattern (split
, &other_tail
, insn_elem
->split
->loc
);
1838 /* Try to apply define_substs to the given ELEM.
1839 Only define_substs, specified via attributes would be applied.
1840 If attribute, requiring define_subst, is set, but no define_subst
1841 was applied, ELEM would be deleted. */
1844 process_substs_on_one_elem (class queue_elem
*elem
,
1845 class queue_elem
*queue
)
1847 class queue_elem
*subst_elem
;
1848 int i
, j
, patterns_match
;
1850 for (subst_elem
= define_subst_queue
;
1851 subst_elem
; subst_elem
= subst_elem
->next
)
1853 int alternatives
, alternatives_subst
;
1855 rtvec subst_pattern_vec
;
1857 if (!has_subst_attribute (elem
, subst_elem
))
1860 /* Compare original rtl-pattern from define_insn with input
1861 pattern from define_subst.
1862 Also, check if numbers of alternatives are the same in all
1864 if (XVECLEN (elem
->data
, 1) != XVECLEN (subst_elem
->data
, 1))
1868 alternatives_subst
= -1;
1869 for (j
= 0; j
< XVECLEN (elem
->data
, 1); j
++)
1871 if (!subst_pattern_match (XVECEXP (elem
->data
, 1, j
),
1872 XVECEXP (subst_elem
->data
, 1, j
),
1879 if (!get_alternatives_number (XVECEXP (elem
->data
, 1, j
),
1880 &alternatives
, subst_elem
->loc
))
1887 /* Check if numbers of alternatives are the same in all
1888 match_operands in output template of define_subst. */
1889 for (j
= 0; j
< XVECLEN (subst_elem
->data
, 3); j
++)
1891 if (!get_alternatives_number (XVECEXP (subst_elem
->data
, 3, j
),
1892 &alternatives_subst
,
1900 if (!patterns_match
)
1903 /* Clear array in which we save occupied indexes of operands. */
1904 memset (used_operands_numbers
, 0, sizeof (used_operands_numbers
));
1906 /* Create a pattern, based on the output one from define_subst. */
1907 subst_pattern_vec
= rtvec_alloc (XVECLEN (subst_elem
->data
, 3));
1908 for (j
= 0; j
< XVECLEN (subst_elem
->data
, 3); j
++)
1910 subst_pattern
= copy_rtx (XVECEXP (subst_elem
->data
, 3, j
));
1912 /* Duplicate constraints in substitute-pattern. */
1913 subst_pattern
= alter_constraints (subst_pattern
, alternatives
,
1914 duplicate_each_alternative
);
1916 subst_pattern
= adjust_operands_numbers (subst_pattern
);
1918 /* Substitute match_dup and match_op_dup in the new pattern and
1919 duplicate constraints. */
1920 subst_pattern
= subst_dup (subst_pattern
, alternatives
,
1921 alternatives_subst
);
1923 replace_duplicating_operands_in_pattern (subst_pattern
);
1925 /* We don't need any constraints in DEFINE_EXPAND. */
1926 if (GET_CODE (elem
->data
) == DEFINE_EXPAND
)
1927 remove_constraints (subst_pattern
);
1929 RTVEC_ELT (subst_pattern_vec
, j
) = subst_pattern
;
1931 XVEC (elem
->data
, 1) = subst_pattern_vec
;
1933 for (i
= 0; i
< MAX_OPERANDS
; i
++)
1934 match_operand_entries_in_pattern
[i
] = NULL
;
1936 if (GET_CODE (elem
->data
) == DEFINE_INSN
)
1938 XTMPL (elem
->data
, 3) =
1939 alter_output_for_subst_insn (elem
->data
, alternatives_subst
);
1940 alter_attrs_for_subst_insn (elem
, alternatives_subst
);
1943 /* Recalculate condition, joining conditions from original and
1944 DEFINE_SUBST input patterns. */
1945 XSTR (elem
->data
, 2)
1946 = rtx_reader_ptr
->join_c_conditions (XSTR (subst_elem
->data
, 2),
1947 XSTR (elem
->data
, 2));
1948 /* Mark that subst was applied by changing attribute from "yes"
1950 change_subst_attribute (elem
, subst_elem
, subst_false
);
1953 /* If ELEM contains a subst attribute with value "yes", then we
1954 expected that a subst would be applied, but it wasn't - so,
1955 we need to remove that elementto avoid duplicating. */
1956 for (subst_elem
= define_subst_queue
;
1957 subst_elem
; subst_elem
= subst_elem
->next
)
1959 if (has_subst_attribute (elem
, subst_elem
))
1961 remove_from_queue (elem
, &queue
);
1967 /* This is a subroutine of mark_operands_used_in_match_dup.
1968 This routine is marks all MATCH_OPERANDs inside PATTERN as occupied. */
1970 mark_operands_from_match_dup (rtx pattern
)
1973 int i
, j
, len
, opno
;
1975 if (GET_CODE (pattern
) == MATCH_OPERAND
1976 || GET_CODE (pattern
) == MATCH_OPERATOR
1977 || GET_CODE (pattern
) == MATCH_PARALLEL
)
1979 opno
= XINT (pattern
, 0);
1980 gcc_assert (opno
>= 0 && opno
< MAX_OPERANDS
);
1981 used_operands_numbers
[opno
] = 1;
1983 fmt
= GET_RTX_FORMAT (GET_CODE (pattern
));
1984 len
= GET_RTX_LENGTH (GET_CODE (pattern
));
1985 for (i
= 0; i
< len
; i
++)
1990 mark_operands_from_match_dup (XEXP (pattern
, i
));
1993 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
1994 mark_operands_from_match_dup (XVECEXP (pattern
, i
, j
));
2000 /* This is a subroutine of adjust_operands_numbers.
2001 It goes through all expressions in PATTERN and when MATCH_DUP is
2002 met, all MATCH_OPERANDs inside it is marked as occupied. The
2003 process of marking is done by routin mark_operands_from_match_dup. */
2005 mark_operands_used_in_match_dup (rtx pattern
)
2008 int i
, j
, len
, opno
;
2010 if (GET_CODE (pattern
) == MATCH_DUP
)
2012 opno
= XINT (pattern
, 0);
2013 gcc_assert (opno
>= 0 && opno
< MAX_OPERANDS
);
2014 mark_operands_from_match_dup (operand_data
[opno
]);
2017 fmt
= GET_RTX_FORMAT (GET_CODE (pattern
));
2018 len
= GET_RTX_LENGTH (GET_CODE (pattern
));
2019 for (i
= 0; i
< len
; i
++)
2024 mark_operands_used_in_match_dup (XEXP (pattern
, i
));
2027 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
2028 mark_operands_used_in_match_dup (XVECEXP (pattern
, i
, j
));
2034 /* This is subroutine of renumerate_operands_in_pattern.
2035 It finds first not-occupied operand-index. */
2037 find_first_unused_number_of_operand ()
2040 for (i
= 0; i
< MAX_OPERANDS
; i
++)
2041 if (!used_operands_numbers
[i
])
2043 return MAX_OPERANDS
;
2046 /* This is subroutine of adjust_operands_numbers.
2047 It visits all expressions in PATTERN and assigns not-occupied
2048 operand indexes to MATCH_OPERANDs and MATCH_OPERATORs of this
2051 renumerate_operands_in_pattern (rtx pattern
)
2055 int i
, j
, len
, new_opno
;
2056 code
= GET_CODE (pattern
);
2058 if (code
== MATCH_OPERAND
2059 || code
== MATCH_OPERATOR
)
2061 new_opno
= find_first_unused_number_of_operand ();
2062 gcc_assert (new_opno
>= 0 && new_opno
< MAX_OPERANDS
);
2063 XINT (pattern
, 0) = new_opno
;
2064 used_operands_numbers
[new_opno
] = 1;
2067 fmt
= GET_RTX_FORMAT (GET_CODE (pattern
));
2068 len
= GET_RTX_LENGTH (GET_CODE (pattern
));
2069 for (i
= 0; i
< len
; i
++)
2074 renumerate_operands_in_pattern (XEXP (pattern
, i
));
2077 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
2078 renumerate_operands_in_pattern (XVECEXP (pattern
, i
, j
));
2084 /* If output pattern of define_subst contains MATCH_DUP, then this
2085 expression would be replaced with the pattern, matched with
2086 MATCH_OPERAND from input pattern. This pattern could contain any
2087 number of MATCH_OPERANDs, MATCH_OPERATORs etc., so it's possible
2088 that a MATCH_OPERAND from output_pattern (if any) would have the
2089 same number, as MATCH_OPERAND from copied pattern. To avoid such
2090 indexes overlapping, we assign new indexes to MATCH_OPERANDs,
2091 laying in the output pattern outside of MATCH_DUPs. */
2093 adjust_operands_numbers (rtx pattern
)
2095 mark_operands_used_in_match_dup (pattern
);
2097 renumerate_operands_in_pattern (pattern
);
2102 /* Generate RTL expression
2106 generate_match_dup (int opno
)
2108 rtx return_rtx
= rtx_alloc (MATCH_DUP
);
2109 PUT_CODE (return_rtx
, MATCH_DUP
);
2110 XINT (return_rtx
, 0) = opno
;
2114 /* This routine checks all match_operands in PATTERN and if some of
2115 have the same index, it replaces all of them except the first one to
2117 Usually, match_operands with the same indexes are forbidden, but
2118 after define_subst copy an RTL-expression from original template,
2119 indexes of existed and just-copied match_operands could coincide.
2120 To fix it, we replace one of them with match_dup. */
2122 replace_duplicating_operands_in_pattern (rtx pattern
)
2125 int i
, j
, len
, opno
;
2128 if (GET_CODE (pattern
) == MATCH_OPERAND
)
2130 opno
= XINT (pattern
, 0);
2131 gcc_assert (opno
>= 0 && opno
< MAX_OPERANDS
);
2132 if (match_operand_entries_in_pattern
[opno
] == NULL
)
2134 match_operand_entries_in_pattern
[opno
] = pattern
;
2139 /* Compare predicates before replacing with match_dup. */
2140 if (strcmp (XSTR (pattern
, 1),
2141 XSTR (match_operand_entries_in_pattern
[opno
], 1)))
2143 error ("duplicated match_operands with different predicates were"
2147 return generate_match_dup (opno
);
2150 fmt
= GET_RTX_FORMAT (GET_CODE (pattern
));
2151 len
= GET_RTX_LENGTH (GET_CODE (pattern
));
2152 for (i
= 0; i
< len
; i
++)
2157 mdup
= replace_duplicating_operands_in_pattern (XEXP (pattern
, i
));
2159 XEXP (pattern
, i
) = mdup
;
2162 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
2165 replace_duplicating_operands_in_pattern (XVECEXP
2168 XVECEXP (pattern
, i
, j
) = mdup
;
2176 /* The routine modifies given input PATTERN of define_subst, replacing
2177 MATCH_DUP and MATCH_OP_DUP with operands from define_insn original
2178 pattern, whose operands are stored in OPERAND_DATA array.
2179 It also duplicates constraints in operands - constraints from
2180 define_insn operands are duplicated N_SUBST_ALT times, constraints
2181 from define_subst operands are duplicated N_ALT times.
2182 After the duplication, returned output rtl-pattern contains every
2183 combination of input constraints Vs constraints from define_subst
2186 subst_dup (rtx pattern
, int n_alt
, int n_subst_alt
)
2190 int i
, j
, len
, opno
;
2192 code
= GET_CODE (pattern
);
2197 opno
= XINT (pattern
, 0);
2199 gcc_assert (opno
>= 0 && opno
< MAX_OPERANDS
);
2201 if (operand_data
[opno
])
2203 pattern
= copy_rtx (operand_data
[opno
]);
2205 /* Duplicate constraints. */
2206 pattern
= alter_constraints (pattern
, n_subst_alt
,
2207 duplicate_alternatives
);
2215 fmt
= GET_RTX_FORMAT (GET_CODE (pattern
));
2216 len
= GET_RTX_LENGTH (GET_CODE (pattern
));
2217 for (i
= 0; i
< len
; i
++)
2222 if (code
!= MATCH_DUP
&& code
!= MATCH_OP_DUP
)
2223 XEXP (pattern
, i
) = subst_dup (XEXP (pattern
, i
),
2224 n_alt
, n_subst_alt
);
2227 if (XVEC (pattern
, i
) == NULL
)
2231 if (code
!= MATCH_DUP
&& code
!= MATCH_OP_DUP
)
2232 for (j
= XVECLEN (pattern
, i
) - 1; j
>= 0; --j
)
2233 XVECEXP (pattern
, i
, j
) = subst_dup (XVECEXP (pattern
, i
, j
),
2234 n_alt
, n_subst_alt
);
2237 case 'r': case 'p': case 'i': case 'w':
2238 case '0': case 's': case 'S': case 'T':
2248 /* If we have any DEFINE_COND_EXEC patterns, expand the DEFINE_INSN
2249 patterns appropriately. */
2252 process_define_cond_exec (void)
2254 class queue_elem
*elem
;
2256 identify_predicable_attribute ();
2260 for (elem
= define_cond_exec_queue
; elem
; elem
= elem
->next
)
2261 process_one_cond_exec (elem
);
2264 /* If we have any DEFINE_SUBST patterns, expand DEFINE_INSN and
2265 DEFINE_EXPAND patterns appropriately. */
2268 process_define_subst (void)
2270 class queue_elem
*elem
, *elem_attr
;
2272 /* Check if each define_subst has corresponding define_subst_attr. */
2273 for (elem
= define_subst_queue
; elem
; elem
= elem
->next
)
2275 for (elem_attr
= define_subst_attr_queue
;
2277 elem_attr
= elem_attr
->next
)
2278 if (strcmp (XSTR (elem
->data
, 0), XSTR (elem_attr
->data
, 1)) == 0)
2281 error_at (elem
->loc
,
2282 "%s: `define_subst' must have at least one "
2283 "corresponding `define_subst_attr'",
2284 XSTR (elem
->data
, 0));
2291 for (elem
= define_insn_queue
; elem
; elem
= elem
->next
)
2292 process_substs_on_one_elem (elem
, define_insn_queue
);
2293 for (elem
= other_queue
; elem
; elem
= elem
->next
)
2295 if (GET_CODE (elem
->data
) != DEFINE_EXPAND
)
2297 process_substs_on_one_elem (elem
, other_queue
);
2301 /* A subclass of rtx_reader which reads .md files and calls process_rtx on
2302 the top-level elements. */
2304 class gen_reader
: public rtx_reader
2307 gen_reader () : rtx_reader (false) {}
2308 void handle_unknown_directive (file_location
, const char *);
2312 gen_reader::handle_unknown_directive (file_location loc
, const char *rtx_name
)
2314 auto_vec
<rtx
, 32> subrtxs
;
2315 if (!read_rtx (rtx_name
, &subrtxs
))
2320 FOR_EACH_VEC_ELT (subrtxs
, i
, x
)
2321 process_rtx (x
, loc
);
2324 /* Comparison function for the mnemonic hash table. */
2327 htab_eq_string (const void *s1
, const void *s2
)
2329 return strcmp ((const char*)s1
, (const char*)s2
) == 0;
2332 /* Add mnemonic STR with length LEN to the mnemonic hash table
2333 MNEMONIC_HTAB. A trailing zero end character is appended to STR
2334 and a permanent heap copy of STR is created. */
2337 add_mnemonic_string (htab_t mnemonic_htab
, const char *str
, size_t len
)
2341 char *str_zero
= (char*)alloca (len
+ 1);
2343 memcpy (str_zero
, str
, len
);
2344 str_zero
[len
] = '\0';
2346 slot
= htab_find_slot (mnemonic_htab
, str_zero
, INSERT
);
2351 /* Not found; create a permanent copy and add it to the hash table. */
2352 new_str
= XNEWVAR (char, len
+ 1);
2353 memcpy (new_str
, str_zero
, len
+ 1);
2357 /* Scan INSN for mnemonic strings and add them to the mnemonic hash
2358 table in MNEMONIC_HTAB.
2360 The mnemonics cannot be found if they are emitted using C code.
2362 If a mnemonic string contains ';' or a newline the string assumed
2363 to consist of more than a single instruction. The attribute value
2364 will then be set to the user defined default value. */
2367 gen_mnemonic_setattr (htab_t mnemonic_htab
, rtx insn
)
2369 const char *template_code
, *cp
;
2375 struct obstack
*string_obstack
= rtx_reader_ptr
->get_string_obstack ();
2377 template_code
= XTMPL (insn
, 3);
2379 /* Skip patterns which use C code to emit the template. */
2380 if (template_code
[0] == '*')
2383 if (template_code
[0] == '@')
2384 cp
= &template_code
[1];
2386 cp
= &template_code
[0];
2390 const char *ep
, *sp
;
2393 while (ISSPACE (*cp
))
2396 for (ep
= sp
= cp
; !IS_VSPACE (*ep
) && *ep
!= '\0'; ++ep
)
2401 obstack_1grow (string_obstack
, ',');
2403 while (cp
< sp
&& ((*cp
>= '0' && *cp
<= '9')
2404 || (*cp
>= 'a' && *cp
<= 'z')))
2407 obstack_1grow (string_obstack
, *cp
);
2414 if (*cp
== ';' || (*cp
== '\\' && cp
[1] == 'n'))
2416 /* Don't set a value if there are more than one
2417 instruction in the string. */
2418 obstack_blank_fast (string_obstack
, -size
);
2427 obstack_1grow (string_obstack
, '*');
2429 add_mnemonic_string (mnemonic_htab
,
2430 (char *) obstack_next_free (string_obstack
) - size
,
2435 /* An insn definition might emit an empty string. */
2436 if (obstack_object_size (string_obstack
) == 0)
2439 obstack_1grow (string_obstack
, '\0');
2441 set_attr
= rtx_alloc (SET_ATTR
);
2442 XSTR (set_attr
, 1) = XOBFINISH (string_obstack
, char *);
2443 attr_name
= XNEWVAR (char, strlen (MNEMONIC_ATTR_NAME
) + 1);
2444 strcpy (attr_name
, MNEMONIC_ATTR_NAME
);
2445 XSTR (set_attr
, 0) = attr_name
;
2447 if (!XVEC (insn
, 4))
2450 vec_len
= XVECLEN (insn
, 4);
2452 new_vec
= rtvec_alloc (vec_len
+ 1);
2453 for (i
= 0; i
< vec_len
; i
++)
2454 RTVEC_ELT (new_vec
, i
) = XVECEXP (insn
, 4, i
);
2455 RTVEC_ELT (new_vec
, vec_len
) = set_attr
;
2456 XVEC (insn
, 4) = new_vec
;
2459 /* This function is called for the elements in the mnemonic hashtable
2460 and generates a comma separated list of the mnemonics. */
2463 mnemonic_htab_callback (void **slot
, void *info ATTRIBUTE_UNUSED
)
2465 struct obstack
*string_obstack
= rtx_reader_ptr
->get_string_obstack ();
2467 obstack_grow (string_obstack
, (char*) *slot
, strlen ((char*) *slot
));
2468 obstack_1grow (string_obstack
, ',');
2472 /* Generate (set_attr "mnemonic" "..") RTXs and append them to every
2473 insn definition in case the back end requests it by defining the
2474 mnemonic attribute. The values for the attribute will be extracted
2475 from the output patterns of the insn definitions as far as
2479 gen_mnemonic_attr (void)
2481 class queue_elem
*elem
;
2482 rtx mnemonic_attr
= NULL
;
2483 htab_t mnemonic_htab
;
2484 const char *str
, *p
;
2486 struct obstack
*string_obstack
= rtx_reader_ptr
->get_string_obstack ();
2491 /* Look for the DEFINE_ATTR for `mnemonic'. */
2492 for (elem
= define_attr_queue
; elem
!= *define_attr_tail
; elem
= elem
->next
)
2493 if (GET_CODE (elem
->data
) == DEFINE_ATTR
2494 && strcmp (XSTR (elem
->data
, 0), MNEMONIC_ATTR_NAME
) == 0)
2496 mnemonic_attr
= elem
->data
;
2500 /* A (define_attr "mnemonic" "...") indicates that the back-end
2501 wants a mnemonic attribute to be generated. */
2505 mnemonic_htab
= htab_create_alloc (MNEMONIC_HTAB_SIZE
, htab_hash_string
,
2506 htab_eq_string
, 0, xcalloc
, free
);
2508 for (elem
= define_insn_queue
; elem
; elem
= elem
->next
)
2510 rtx insn
= elem
->data
;
2513 /* Check if the insn definition already has
2514 (set_attr "mnemonic" ...) or (set (attr "mnemonic") ...). */
2516 for (i
= 0; i
< XVECLEN (insn
, 4); i
++)
2518 rtx set_attr
= XVECEXP (insn
, 4, i
);
2520 switch (GET_CODE (set_attr
))
2523 case SET_ATTR_ALTERNATIVE
:
2524 if (strcmp (XSTR (set_attr
, 0), MNEMONIC_ATTR_NAME
) == 0)
2528 if (GET_CODE (SET_DEST (set_attr
)) == ATTR
2529 && strcmp (XSTR (SET_DEST (set_attr
), 0),
2530 MNEMONIC_ATTR_NAME
) == 0)
2539 gen_mnemonic_setattr (mnemonic_htab
, insn
);
2542 /* Add the user defined values to the hash table. */
2543 str
= XSTR (mnemonic_attr
, 1);
2544 while ((p
= scan_comma_elt (&str
)) != NULL
)
2545 add_mnemonic_string (mnemonic_htab
, p
, str
- p
);
2547 htab_traverse (mnemonic_htab
, mnemonic_htab_callback
, NULL
);
2549 /* Replace the last ',' with the zero end character. */
2550 *((char *) obstack_next_free (string_obstack
) - 1) = '\0';
2551 XSTR (mnemonic_attr
, 1) = XOBFINISH (string_obstack
, char *);
2554 /* Check if there are DEFINE_ATTRs with the same name. */
2556 check_define_attr_duplicates ()
2558 class queue_elem
*elem
;
2563 attr_htab
= htab_create (500, htab_hash_string
, htab_eq_string
, NULL
);
2565 for (elem
= define_attr_queue
; elem
; elem
= elem
->next
)
2567 attr_name
= xstrdup (XSTR (elem
->data
, 0));
2569 slot
= htab_find_slot (attr_htab
, attr_name
, INSERT
);
2574 error_at (elem
->loc
, "redefinition of attribute '%s'", attr_name
);
2575 htab_delete (attr_htab
);
2582 htab_delete (attr_htab
);
2585 /* The entry point for initializing the reader. */
2588 init_rtx_reader_args_cb (int argc
, const char **argv
,
2589 bool (*parse_opt
) (const char *))
2591 /* Prepare to read input. */
2592 condition_table
= htab_create (500, hash_c_test
, cmp_c_test
, NULL
);
2593 init_predicate_table ();
2594 obstack_init (rtl_obstack
);
2596 /* Start at 1, to make 0 available for CODE_FOR_nothing. */
2597 insn_sequence_num
= 1;
2599 /* These sequences are not used as indices, so can start at 1 also. */
2600 split_sequence_num
= 1;
2601 peephole2_sequence_num
= 1;
2603 gen_reader
*reader
= new gen_reader ();
2604 reader
->read_md_files (argc
, argv
, parse_opt
);
2606 if (define_attr_queue
!= NULL
)
2607 check_define_attr_duplicates ();
2609 /* Process define_cond_exec patterns. */
2610 if (define_cond_exec_queue
!= NULL
)
2611 process_define_cond_exec ();
2613 /* Process define_subst patterns. */
2614 if (define_subst_queue
!= NULL
)
2615 process_define_subst ();
2617 if (define_attr_queue
!= NULL
)
2618 gen_mnemonic_attr ();
2629 /* Programs that don't have their own options can use this entry point
2632 init_rtx_reader_args (int argc
, const char **argv
)
2634 return init_rtx_reader_args_cb (argc
, argv
, 0);
2637 /* Try to read a single rtx from the file. Return true on success,
2638 describing it in *INFO. */
2641 read_md_rtx (md_rtx_info
*info
)
2643 int truth
, *counter
;
2646 /* Discard insn patterns which we know can never match (because
2647 their C test is provably always false). If insn_elision is
2648 false, our caller needs to see all the patterns. Note that the
2649 elided patterns are never counted by the sequence numbering; it
2650 is the caller's responsibility, when insn_elision is false, not
2651 to use elided pattern numbers for anything. */
2654 class queue_elem
**queue
, *elem
;
2656 /* Read all patterns from a given queue before moving on to the next. */
2657 if (define_attr_queue
!= NULL
)
2658 queue
= &define_attr_queue
;
2659 else if (define_pred_queue
!= NULL
)
2660 queue
= &define_pred_queue
;
2661 else if (define_insn_queue
!= NULL
)
2662 queue
= &define_insn_queue
;
2663 else if (other_queue
!= NULL
)
2664 queue
= &other_queue
;
2669 *queue
= elem
->next
;
2672 info
->loc
= elem
->loc
;
2675 truth
= maybe_eval_c_test (get_c_test (def
));
2677 while (truth
== 0 && insn_elision
);
2679 /* Perform code-specific processing and pick the appropriate sequence
2681 switch (GET_CODE (def
))
2685 /* insn_sequence_num is used here so the name table will match caller's
2686 idea of insn numbering, whether or not elision is active. */
2687 record_insn_name (insn_sequence_num
, XSTR (def
, 0));
2690 case DEFINE_PEEPHOLE
:
2691 counter
= &insn_sequence_num
;
2695 counter
= &split_sequence_num
;
2698 case DEFINE_PEEPHOLE2
:
2699 counter
= &peephole2_sequence_num
;
2709 info
->index
= *counter
;
2717 rtx_locs
= new hash_map
<rtx
, file_location
>;
2718 rtx_locs
->put (info
->def
, info
->loc
);
2723 /* Return the file location of DEFINE_* rtx X, which was previously
2724 returned by read_md_rtx. */
2726 get_file_location (rtx x
)
2728 gcc_assert (rtx_locs
);
2729 file_location
*entry
= rtx_locs
->get (x
);
2734 /* Return the number of possible INSN_CODEs. Only meaningful once the
2735 whole file has been processed. */
2737 get_num_insn_codes ()
2739 return insn_sequence_num
;
2742 /* Return the C test that says whether definition rtx DEF can be used,
2743 or "" if it can be used unconditionally. */
2748 switch (GET_CODE (x
))
2756 case DEFINE_PEEPHOLE
:
2757 case DEFINE_PEEPHOLE2
:
2765 /* Helper functions for insn elision. */
2767 /* Compute a hash function of a c_test structure, which is keyed
2768 by its ->expr field. */
2770 hash_c_test (const void *x
)
2772 const struct c_test
*a
= (const struct c_test
*) x
;
2773 const unsigned char *base
, *s
= (const unsigned char *) a
->expr
;
2781 while ((c
= *s
++) != '\0')
2783 hash
+= c
+ (c
<< 17);
2788 hash
+= len
+ (len
<< 17);
2794 /* Compare two c_test expression structures. */
2796 cmp_c_test (const void *x
, const void *y
)
2798 const struct c_test
*a
= (const struct c_test
*) x
;
2799 const struct c_test
*b
= (const struct c_test
*) y
;
2801 return !strcmp (a
->expr
, b
->expr
);
2804 /* Given a string representing a C test expression, look it up in the
2805 condition_table and report whether or not its value is known
2806 at compile time. Returns a tristate: 1 for known true, 0 for
2807 known false, -1 for unknown. */
2809 maybe_eval_c_test (const char *expr
)
2811 const struct c_test
*test
;
2812 struct c_test dummy
;
2818 test
= (const struct c_test
*)htab_find (condition_table
, &dummy
);
2824 /* Record the C test expression EXPR in the condition_table, with
2825 value VAL. Duplicates clobber previous entries. */
2828 add_c_test (const char *expr
, int value
)
2830 struct c_test
*test
;
2835 test
= XNEW (struct c_test
);
2837 test
->value
= value
;
2839 *(htab_find_slot (condition_table
, test
, INSERT
)) = test
;
2842 /* For every C test, call CALLBACK with two arguments: a pointer to
2843 the condition structure and INFO. Stops when CALLBACK returns zero. */
2845 traverse_c_tests (htab_trav callback
, void *info
)
2847 if (condition_table
)
2848 htab_traverse (condition_table
, callback
, info
);
2851 /* Helper functions for define_predicate and define_special_predicate
2852 processing. Shared between genrecog.c and genpreds.c. */
2854 static htab_t predicate_table
;
2855 struct pred_data
*first_predicate
;
2856 static struct pred_data
**last_predicate
= &first_predicate
;
2859 hash_struct_pred_data (const void *ptr
)
2861 return htab_hash_string (((const struct pred_data
*)ptr
)->name
);
2865 eq_struct_pred_data (const void *a
, const void *b
)
2867 return !strcmp (((const struct pred_data
*)a
)->name
,
2868 ((const struct pred_data
*)b
)->name
);
2872 lookup_predicate (const char *name
)
2874 struct pred_data key
;
2876 return (struct pred_data
*) htab_find (predicate_table
, &key
);
2879 /* Record that predicate PRED can accept CODE. */
2882 add_predicate_code (struct pred_data
*pred
, enum rtx_code code
)
2884 if (!pred
->codes
[code
])
2887 pred
->codes
[code
] = true;
2889 if (GET_RTX_CLASS (code
) != RTX_CONST_OBJ
)
2890 pred
->allows_non_const
= true;
2897 && code
!= STRICT_LOW_PART
2898 && code
!= ZERO_EXTRACT
2900 pred
->allows_non_lvalue
= true;
2902 if (pred
->num_codes
== 1)
2903 pred
->singleton
= code
;
2904 else if (pred
->num_codes
== 2)
2905 pred
->singleton
= UNKNOWN
;
2910 add_predicate (struct pred_data
*pred
)
2912 void **slot
= htab_find_slot (predicate_table
, pred
, INSERT
);
2915 error ("duplicate predicate definition for '%s'", pred
->name
);
2919 *last_predicate
= pred
;
2920 last_predicate
= &pred
->next
;
2923 /* This array gives the initial content of the predicate table. It
2924 has entries for all predicates defined in recog.c. */
2926 struct std_pred_table
2930 bool allows_const_p
;
2931 RTX_CODE codes
[NUM_RTX_CODE
];
2934 static const struct std_pred_table std_preds
[] = {
2935 {"general_operand", false, true, {SUBREG
, REG
, MEM
}},
2936 {"address_operand", true, true, {SUBREG
, REG
, MEM
, PLUS
, MINUS
, MULT
,
2937 ZERO_EXTEND
, SIGN_EXTEND
, AND
}},
2938 {"register_operand", false, false, {SUBREG
, REG
}},
2939 {"pmode_register_operand", true, false, {SUBREG
, REG
}},
2940 {"scratch_operand", false, false, {SCRATCH
, REG
}},
2941 {"immediate_operand", false, true, {UNKNOWN
}},
2942 {"const_int_operand", false, false, {CONST_INT
}},
2943 #if TARGET_SUPPORTS_WIDE_INT
2944 {"const_scalar_int_operand", false, false, {CONST_INT
, CONST_WIDE_INT
}},
2945 {"const_double_operand", false, false, {CONST_DOUBLE
}},
2947 {"const_double_operand", false, false, {CONST_INT
, CONST_DOUBLE
}},
2949 {"nonimmediate_operand", false, false, {SUBREG
, REG
, MEM
}},
2950 {"nonmemory_operand", false, true, {SUBREG
, REG
}},
2951 {"push_operand", false, false, {MEM
}},
2952 {"pop_operand", false, false, {MEM
}},
2953 {"memory_operand", false, false, {SUBREG
, MEM
}},
2954 {"indirect_operand", false, false, {SUBREG
, MEM
}},
2955 {"ordered_comparison_operator", false, false, {EQ
, NE
,
2957 LEU
, LTU
, GEU
, GTU
}},
2958 {"comparison_operator", false, false, {EQ
, NE
,
2965 #define NUM_KNOWN_STD_PREDS ARRAY_SIZE (std_preds)
2967 /* Initialize the table of predicate definitions, starting with
2968 the information we have on generic predicates. */
2971 init_predicate_table (void)
2974 struct pred_data
*pred
;
2976 predicate_table
= htab_create_alloc (37, hash_struct_pred_data
,
2977 eq_struct_pred_data
, 0,
2980 for (i
= 0; i
< NUM_KNOWN_STD_PREDS
; i
++)
2982 pred
= XCNEW (struct pred_data
);
2983 pred
->name
= std_preds
[i
].name
;
2984 pred
->special
= std_preds
[i
].special
;
2986 for (j
= 0; std_preds
[i
].codes
[j
] != 0; j
++)
2987 add_predicate_code (pred
, std_preds
[i
].codes
[j
]);
2989 if (std_preds
[i
].allows_const_p
)
2990 for (j
= 0; j
< NUM_RTX_CODE
; j
++)
2991 if (GET_RTX_CLASS (j
) == RTX_CONST_OBJ
)
2992 add_predicate_code (pred
, (enum rtx_code
) j
);
2994 add_predicate (pred
);
2998 /* These functions allow linkage with print-rtl.c. Also, some generators
2999 like to annotate their output with insn names. */
3001 /* Holds an array of names indexed by insn_code_number. */
3002 static char **insn_name_ptr
= 0;
3003 static int insn_name_ptr_size
= 0;
3006 get_insn_name (int code
)
3008 if (code
< insn_name_ptr_size
)
3009 return insn_name_ptr
[code
];
3015 record_insn_name (int code
, const char *name
)
3017 static const char *last_real_name
= "insn";
3018 static int last_real_code
= 0;
3021 if (insn_name_ptr_size
<= code
)
3024 new_size
= (insn_name_ptr_size
? insn_name_ptr_size
* 2 : 512);
3025 insn_name_ptr
= XRESIZEVEC (char *, insn_name_ptr
, new_size
);
3026 memset (insn_name_ptr
+ insn_name_ptr_size
, 0,
3027 sizeof (char *) * (new_size
- insn_name_ptr_size
));
3028 insn_name_ptr_size
= new_size
;
3031 if (!name
|| name
[0] == '\0')
3033 new_name
= XNEWVAR (char, strlen (last_real_name
) + 10);
3034 sprintf (new_name
, "%s+%d", last_real_name
, code
- last_real_code
);
3038 last_real_name
= new_name
= xstrdup (name
);
3039 last_real_code
= code
;
3042 insn_name_ptr
[code
] = new_name
;
3045 /* Make STATS describe the operands that appear in rtx X. */
3048 get_pattern_stats_1 (struct pattern_stats
*stats
, rtx x
)
3058 code
= GET_CODE (x
);
3062 case MATCH_OPERATOR
:
3063 case MATCH_PARALLEL
:
3064 stats
->max_opno
= MAX (stats
->max_opno
, XINT (x
, 0));
3071 stats
->max_dup_opno
= MAX (stats
->max_dup_opno
, XINT (x
, 0));
3075 if (stats
->min_scratch_opno
== -1)
3076 stats
->min_scratch_opno
= XINT (x
, 0);
3078 stats
->min_scratch_opno
= MIN (stats
->min_scratch_opno
, XINT (x
, 0));
3079 stats
->max_scratch_opno
= MAX (stats
->max_scratch_opno
, XINT (x
, 0));
3086 fmt
= GET_RTX_FORMAT (code
);
3087 len
= GET_RTX_LENGTH (code
);
3088 for (i
= 0; i
< len
; i
++)
3090 if (fmt
[i
] == 'e' || fmt
[i
] == 'u')
3091 get_pattern_stats_1 (stats
, XEXP (x
, i
));
3092 else if (fmt
[i
] == 'E')
3095 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
3096 get_pattern_stats_1 (stats
, XVECEXP (x
, i
, j
));
3101 /* Make STATS describe the operands that appear in instruction pattern
3105 get_pattern_stats (struct pattern_stats
*stats
, rtvec pattern
)
3109 stats
->max_opno
= -1;
3110 stats
->max_dup_opno
= -1;
3111 stats
->min_scratch_opno
= -1;
3112 stats
->max_scratch_opno
= -1;
3113 stats
->num_dups
= 0;
3115 len
= GET_NUM_ELEM (pattern
);
3116 for (i
= 0; i
< len
; i
++)
3117 get_pattern_stats_1 (stats
, RTVEC_ELT (pattern
, i
));
3119 stats
->num_generator_args
= stats
->max_opno
+ 1;
3120 stats
->num_insn_operands
= MAX (stats
->max_opno
,
3121 stats
->max_scratch_opno
) + 1;
3122 stats
->num_operand_vars
= MAX (stats
->max_opno
,
3123 MAX (stats
->max_dup_opno
,
3124 stats
->max_scratch_opno
)) + 1;
3127 /* Return the emit_* function that should be used for pattern X, or NULL
3128 if we can't pick a particular type at compile time and should instead
3129 fall back to "emit". */
3132 get_emit_function (rtx x
)
3134 switch (classify_insn (x
))
3140 return "emit_call_insn";
3143 return "emit_jump_insn";
3153 /* Return true if we must emit a barrier after pattern X. */
3156 needs_barrier_p (rtx x
)
3158 return (GET_CODE (x
) == SET
3159 && GET_CODE (SET_DEST (x
)) == PC
3160 && GET_CODE (SET_SRC (x
)) == LABEL_REF
);
3165 #define OPTAB_CL(o, p, c, b, l) { #o, p, #b, ZS, #l, o, c, UNKNOWN, 1 },
3166 #define OPTAB_CX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 1 },
3167 #define OPTAB_CD(o, p) { #o, p, NS, ZS, NS, o, UNKNOWN, UNKNOWN, 2 },
3168 #define OPTAB_NL(o, p, c, b, s, l) { #o, p, #b, #s, #l, o, c, c, 3 },
3169 #define OPTAB_NC(o, p, c) { #o, p, NS, ZS, NS, o, c, c, 3 },
3170 #define OPTAB_NX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 3 },
3171 #define OPTAB_VL(o, p, c, b, s, l) { #o, p, #b, #s, #l, o, c, UNKNOWN, 3 },
3172 #define OPTAB_VC(o, p, c) { #o, p, NS, ZS, NS, o, c, UNKNOWN, 3 },
3173 #define OPTAB_VX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 3 },
3174 #define OPTAB_DC(o, p, c) { #o, p, NS, ZS, NS, o, c, c, 4 },
3175 #define OPTAB_D(o, p) { #o, p, NS, ZS, NS, o, UNKNOWN, UNKNOWN, 4 },
3177 /* An array of all optabs. Note that the same optab can appear more
3178 than once, with a different pattern. */
3179 optab_def optabs
[] = {
3180 { "unknown_optab", NULL
, NS
, ZS
, NS
, unknown_optab
, UNKNOWN
, UNKNOWN
, 0 },
3181 #include "optabs.def"
3184 /* The number of entries in optabs[]. */
3185 unsigned int num_optabs
= ARRAY_SIZE (optabs
);
3199 /* Return true if instruction NAME matches pattern PAT, storing information
3200 about the match in P if so. */
3203 match_pattern (optab_pattern
*p
, const char *name
, const char *pat
)
3205 bool force_float
= false;
3206 bool force_int
= false;
3207 bool force_partial_int
= false;
3208 bool force_fixed
= false;
3216 if (*pat
!= *name
++)
3228 force_partial_int
= 1;
3242 /* This loop will stop at the first prefix match, so
3243 look through the modes in reverse order, in case
3244 there are extra CC modes and CC is a prefix of the
3245 CC modes (as it should be). */
3246 for (i
= (MAX_MACHINE_MODE
) - 1; i
>= 0; i
--)
3249 for (p
= GET_MODE_NAME (i
), q
= name
; *p
; p
++, q
++)
3250 if (TOLOWER (*p
) != *q
)
3253 && (! force_int
|| mode_class
[i
] == MODE_INT
3254 || mode_class
[i
] == MODE_VECTOR_INT
)
3255 && (! force_partial_int
3256 || mode_class
[i
] == MODE_INT
3257 || mode_class
[i
] == MODE_PARTIAL_INT
3258 || mode_class
[i
] == MODE_VECTOR_INT
)
3260 || mode_class
[i
] == MODE_FLOAT
3261 || mode_class
[i
] == MODE_DECIMAL_FLOAT
3262 || mode_class
[i
] == MODE_COMPLEX_FLOAT
3263 || mode_class
[i
] == MODE_VECTOR_FLOAT
)
3265 || mode_class
[i
] == MODE_FRACT
3266 || mode_class
[i
] == MODE_UFRACT
3267 || mode_class
[i
] == MODE_ACCUM
3268 || mode_class
[i
] == MODE_UACCUM
3269 || mode_class
[i
] == MODE_VECTOR_FRACT
3270 || mode_class
[i
] == MODE_VECTOR_UFRACT
3271 || mode_class
[i
] == MODE_VECTOR_ACCUM
3272 || mode_class
[i
] == MODE_VECTOR_UACCUM
))
3278 name
+= strlen (GET_MODE_NAME (i
));
3285 force_partial_int
= false;
3286 force_float
= false;
3287 force_fixed
= false;
3297 /* Return true if NAME is the name of an optab, describing it in P if so. */
3300 find_optab (optab_pattern
*p
, const char *name
)
3302 if (*name
== 0 || *name
== '*')
3305 /* See if NAME matches one of the patterns we have for the optabs
3307 for (unsigned int pindex
= 0; pindex
< ARRAY_SIZE (optabs
); pindex
++)
3310 if (match_pattern (p
, name
, optabs
[pindex
].pattern
))
3313 p
->op
= optabs
[pindex
].op
;
3314 p
->sort_num
= (p
->op
<< 16) | (p
->m2
<< 8) | p
->m1
;