aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2000-11-09 16:07:52 -0800
committerRichard Henderson <rth@gcc.gnu.org>2000-11-09 16:07:52 -0800
commitc0e3f87d491b3a0e99cfc95717753d130006dfd7 (patch)
tree81000bdb8af0934c8ad62ab5fc920b9abf37512e
parent662f340b8118ce91205c91d73729a5f2f7684f80 (diff)
downloadgcc-c0e3f87d491b3a0e99cfc95717753d130006dfd7.zip
gcc-c0e3f87d491b3a0e99cfc95717753d130006dfd7.tar.gz
gcc-c0e3f87d491b3a0e99cfc95717753d130006dfd7.tar.bz2
recog.c (validate_replace_rtx_1): Consider subregs when replacing a register with a constant inside a...
* recog.c (validate_replace_rtx_1): Consider subregs when replacing a register with a constant inside a sign/zero_extend. From-SVN: r37352
-rw-r--r--gcc/ChangeLog3
-rw-r--r--gcc/recog.c27
2 files changed, 24 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e0fe0ed..d8dde6a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,8 @@
2000-11-09 Richard Henderson <rth@redhat.com>
+ * recog.c (validate_replace_rtx_1): Consider subregs when
+ replacing a register with a constant inside a sign/zero_extend.
+
* config/alpha/linux.h (HANDLE_PRAGMA_PACK_PUSH_POP): Define.
2000-11-09 Geoffrey Keating <geoffk@redhat.com>
diff --git a/gcc/recog.c b/gcc/recog.c
index b8b532e..c01f884 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);