diff options
author | James Greenhalgh <james.greenhalgh@arm.com> | 2014-09-19 10:37:40 +0000 |
---|---|---|
committer | James Greenhalgh <jgreenhalgh@gcc.gnu.org> | 2014-09-19 10:37:40 +0000 |
commit | 5fd4bc96306dccae16acb28c38ab63f213555c04 (patch) | |
tree | 8bd390b80abad2692fc08820202511642a15bafb /gcc/genrecog.c | |
parent | 727dc1217d05e7879a782b534deb0ec65bce5c91 (diff) | |
download | gcc-5fd4bc96306dccae16acb28c38ab63f213555c04.zip gcc-5fd4bc96306dccae16acb28c38ab63f213555c04.tar.gz gcc-5fd4bc96306dccae16acb28c38ab63f213555c04.tar.bz2 |
[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.c | 55 |
1 files changed, 44 insertions, 11 deletions
diff --git a/gcc/genrecog.c b/gcc/genrecog.c index dbdefb0..b3b5bb4 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. */ |