aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2004-12-02 10:31:26 -0800
committerRichard Henderson <rth@gcc.gnu.org>2004-12-02 10:31:26 -0800
commit6b1326732bdf889ce830b6c2d238acea28ec4930 (patch)
tree4f3f14e10e3132e1dd06c628f3a496fb44bcf651
parentdea1c1c5366ffb20410328c725af453484fd8dcb (diff)
downloadgcc-6b1326732bdf889ce830b6c2d238acea28ec4930.zip
gcc-6b1326732bdf889ce830b6c2d238acea28ec4930.tar.gz
gcc-6b1326732bdf889ce830b6c2d238acea28ec4930.tar.bz2
optabs.c (lowpart_subreg_maybe_copy): New.
* optabs.c (lowpart_subreg_maybe_copy): New. (expand_unop, expand_abs_nojump): Use it. From-SVN: r91650
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/optabs.c26
2 files changed, 29 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b91e928..96ef779 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2004-12-02 Richard Henderson <rth@redhat.com>
+
+ * optabs.c (lowpart_subreg_maybe_copy): New.
+ (expand_unop, expand_abs_nojump): Use it.
+
2004-12-02 J"orn Rennecke <joern.rennecke@st.com>
* sh.md (extv, extzv): Add pattern predicate.
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 14f2b72..abf8e29 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)));