summaryrefslogtreecommitdiff
path: root/gcc/genrecog.c
diff options
context:
space:
mode:
authorJames Greenhalgh <james.greenhalgh@arm.com>2014-09-19 10:37:40 +0000
committerJames Greenhalgh <jgreenhalgh@gcc.gnu.org>2014-09-19 10:37:40 +0000
commit5fd4bc96306dccae16acb28c38ab63f213555c04 (patch)
tree8bd390b80abad2692fc08820202511642a15bafb /gcc/genrecog.c
parent727dc1217d05e7879a782b534deb0ec65bce5c91 (diff)
[Patch] Teach genrecog/genoutput that scratch registers require write constraint modifiers
gcc/ * doc/md.texi (Modifiers): Consistently use "read/write" nomenclature rather than "input/output". * genrecog.c (constraints_supported_in_insn_p): New. (validate_pattern): If needed, also check constraints on MATCH_SCRATCH operands. * genoutput.c (validate_insn_alternatives): Catch earlyclobber operands with no '=' or '+' modifier. From-SVN: r215388
Diffstat (limited to 'gcc/genrecog.c')
-rw-r--r--gcc/genrecog.c55
1 files changed, 44 insertions, 11 deletions
diff --git a/gcc/genrecog.c b/gcc/genrecog.c
index dbdefb07d19..b3b5bb46add 100644
--- a/gcc/genrecog.c
+++ b/gcc/genrecog.c
@@ -415,6 +415,18 @@ find_matching_operand (rtx pattern, int n)
return NULL;
}
+/* In DEFINE_EXPAND, DEFINE_SPLIT, and DEFINE_PEEPHOLE2, we
+ don't use the MATCH_OPERAND constraint, only the predicate.
+ This is confusing to folks doing new ports, so help them
+ not make the mistake. */
+
+static bool
+constraints_supported_in_insn_p (rtx insn)
+{
+ return !(GET_CODE (insn) == DEFINE_EXPAND
+ || GET_CODE (insn) == DEFINE_SPLIT
+ || GET_CODE (insn) == DEFINE_PEEPHOLE2);
+}
/* Check for various errors in patterns. SET is nonnull for a destination,
and is the complete set pattern. SET_CODE is '=' for normal sets, and
@@ -432,7 +444,32 @@ validate_pattern (rtx pattern, rtx insn, rtx set, int set_code)
switch (code)
{
case MATCH_SCRATCH:
- return;
+ {
+ const char constraints0 = XSTR (pattern, 1)[0];
+
+ if (!constraints_supported_in_insn_p (insn))
+ {
+ if (constraints0)
+ {
+ error_with_line (pattern_lineno,
+ "constraints not supported in %s",
+ rtx_name[GET_CODE (insn)]);
+ }
+ return;
+ }
+
+ /* If a MATCH_SCRATCH is used in a context requiring an write-only
+ or read/write register, validate that. */
+ if (set_code == '='
+ && constraints0 != '='
+ && constraints0 != '+')
+ {
+ error_with_line (pattern_lineno,
+ "operand %d missing output reload",
+ XINT (pattern, 0));
+ }
+ return;
+ }
case MATCH_DUP:
case MATCH_OP_DUP:
case MATCH_PAR_DUP:
@@ -467,18 +504,14 @@ validate_pattern (rtx pattern, rtx insn, rtx set, int set_code)
{
const char constraints0 = XSTR (pattern, 2)[0];
- /* In DEFINE_EXPAND, DEFINE_SPLIT, and DEFINE_PEEPHOLE2, we
- don't use the MATCH_OPERAND constraint, only the predicate.
- This is confusing to folks doing new ports, so help them
- not make the mistake. */
- if (GET_CODE (insn) == DEFINE_EXPAND
- || GET_CODE (insn) == DEFINE_SPLIT
- || GET_CODE (insn) == DEFINE_PEEPHOLE2)
+ if (!constraints_supported_in_insn_p (insn))
{
if (constraints0)
- error_with_line (pattern_lineno,
- "constraints not supported in %s",
- rtx_name[GET_CODE (insn)]);
+ {
+ error_with_line (pattern_lineno,
+ "constraints not supported in %s",
+ rtx_name[GET_CODE (insn)]);
+ }
}
/* A MATCH_OPERAND that is a SET should have an output reload. */