From 6b1326732bdf889ce830b6c2d238acea28ec4930 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Thu, 2 Dec 2004 10:31:26 -0800 Subject: optabs.c (lowpart_subreg_maybe_copy): New. * optabs.c (lowpart_subreg_maybe_copy): New. (expand_unop, expand_abs_nojump): Use it. From-SVN: r91650 --- gcc/optabs.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'gcc/optabs.c') 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))); -- cgit v1.1