aboutsummaryrefslogtreecommitdiff
path: root/gcc/optabs.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2004-12-02 18:31:26 +0000
committerRichard Henderson <rth@redhat.com>2004-12-02 18:31:26 +0000
commitd60aee1eec32b995abbdcf42da7dde1aa8eb2a63 (patch)
tree4f3f14e10e3132e1dd06c628f3a496fb44bcf651 /gcc/optabs.c
parent6a28ff72495eba97ebcc8b1c64612d6f3290721d (diff)
* optabs.c (lowpart_subreg_maybe_copy): New.
(expand_unop, expand_abs_nojump): Use it. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@91650 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/optabs.c')
-rw-r--r--gcc/optabs.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 14f2b72350c..abf8e296f24 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -2131,6 +2131,26 @@ expand_parity (enum machine_mode mode, rtx op0, rtx target)
return 0;
}
+/* Extract the OMODE lowpart from VAL, which has IMODE. Under certain
+ conditions, VAL may already be a SUBREG against which we cannot generate
+ a further SUBREG. In this case, we expect forcing the value into a
+ register will work around the situation. */
+
+static rtx
+lowpart_subreg_maybe_copy (enum machine_mode omode, rtx val,
+ enum machine_mode imode)
+{
+ rtx ret;
+ ret = lowpart_subreg (omode, val, imode);
+ if (ret == NULL)
+ {
+ val = force_reg (imode, val);
+ ret = lowpart_subreg (omode, val, imode);
+ gcc_assert (ret != NULL);
+ }
+ return ret;
+}
+
/* Generate code to perform an operation specified by UNOPTAB
on operand OP0, with result having machine-mode MODE.
@@ -2322,7 +2342,8 @@ expand_unop (enum machine_mode mode, optab unoptab, rtx op0, rtx target,
rtx insn;
if (target == 0)
target = gen_reg_rtx (mode);
- insn = emit_move_insn (target, gen_lowpart (mode, temp));
+ temp = lowpart_subreg_maybe_copy (mode, temp, imode);
+ insn = emit_move_insn (target, temp);
set_unique_reg_note (insn, REG_EQUAL,
gen_rtx_fmt_e (NEG, mode,
copy_rtx (op0)));
@@ -2513,7 +2534,8 @@ expand_abs_nojump (enum machine_mode mode, rtx op0, rtx target,
rtx insn;
if (target == 0)
target = gen_reg_rtx (mode);
- insn = emit_move_insn (target, gen_lowpart (mode, temp));
+ temp = lowpart_subreg_maybe_copy (mode, temp, imode);
+ insn = emit_move_insn (target, temp);
set_unique_reg_note (insn, REG_EQUAL,
gen_rtx_fmt_e (ABS, mode,
copy_rtx (op0)));