summaryrefslogtreecommitdiff
path: root/gcc/recog.c
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2000-11-10 00:07:52 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2000-11-10 00:07:52 +0000
commit332e65277d599f0975ec390c2e009d22082d0ac0 (patch)
tree81000bdb8af0934c8ad62ab5fc920b9abf37512e /gcc/recog.c
parent076ea9c42772d6d347a069a083ecbd1583576a46 (diff)
downloadgcc-332e65277d599f0975ec390c2e009d22082d0ac0.tar.gz
* recog.c (validate_replace_rtx_1): Consider subregs when
replacing a register with a constant inside a sign/zero_extend. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@37352 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/recog.c')
-rw-r--r--gcc/recog.c27
1 files changed, 21 insertions, 6 deletions
diff --git a/gcc/recog.c b/gcc/recog.c
index b8b532e2403..c01f884ebb4 100644
--- a/gcc/recog.c
+++ b/gcc/recog.c
@@ -480,14 +480,29 @@ validate_replace_rtx_1 (loc, from, to, object)
/* In these cases, the operation to be performed depends on the mode
of the operand. If we are replacing the operand with a VOIDmode
constant, we lose the information. So try to simplify the operation
- in that case. If it fails, substitute in something that we know
- won't be recognized. */
+ in that case. */
if (GET_MODE (to) == VOIDmode
- && rtx_equal_p (XEXP (x, 0), from))
+ && (rtx_equal_p (XEXP (x, 0), from)
+ || (GET_CODE (XEXP (x, 0)) == SUBREG
+ && rtx_equal_p (SUBREG_REG (XEXP (x, 0)), from))))
{
- rtx new = simplify_unary_operation (code, GET_MODE (x), to,
- GET_MODE (from));
- if (new == 0)
+ rtx new = NULL_RTX;
+
+ /* If there is a subreg involved, crop to the portion of the
+ constant that we are interested in. */
+ if (GET_CODE (XEXP (x, 0)) == SUBREG)
+ to = operand_subword (to, SUBREG_WORD (XEXP (x, 0)),
+ 0, GET_MODE (from));
+
+ /* If the above didn't fail, perform the extension from the
+ mode of the operand (and not the mode of FROM). */
+ if (to)
+ new = simplify_unary_operation (code, GET_MODE (x), to,
+ GET_MODE (XEXP (x, 0)));
+
+ /* If any of the above failed, substitute in something that
+ we know won't be recognized. */
+ if (!new)
new = gen_rtx_CLOBBER (GET_MODE (x), const0_rtx);
validate_change (object, loc, new, 1);