From 82dfb9a58fa7f797c1a9e49708fe9ed273ba4f70 Mon Sep 17 00:00:00 2001 From: Roger Sayle Date: Fri, 28 Jan 2005 17:49:47 +0000 Subject: [PATCH] expmed.c (expand_mult_highpart_optab): When attempting to use a non-widening multiplication in a wider mode... * expmed.c (expand_mult_highpart_optab): When attempting to use a non-widening multiplication in a wider mode, the operands need to be converted (zero or sign extended) to that mode. From-SVN: r94383 --- gcc/ChangeLog | 6 ++++++ gcc/expmed.c | 20 +++++++++++++++++--- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 97410c0c10fd..08fc4c27e0e2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2005-01-28 Roger Sayle + + * expmed.c (expand_mult_highpart_optab): When attempting to use + a non-widening multiplication in a wider mode, the operands need + to be converted (zero or sign extended) to that mode. + 2005-01-28 Ian Lance Taylor PR middle-end/16558 diff --git a/gcc/expmed.c b/gcc/expmed.c index 1091c454064a..87a219d2605f 100644 --- a/gcc/expmed.c +++ b/gcc/expmed.c @@ -3332,15 +3332,29 @@ expand_mult_highpart_optab (enum machine_mode mode, rtx op0, rtx op1, } /* Try widening the mode and perform a non-widening multiplication. */ - moptab = smul_optab; if (smul_optab->handlers[wider_mode].insn_code != CODE_FOR_nothing && size - 1 < BITS_PER_WORD && mul_cost[wider_mode] + shift_cost[mode][size-1] < max_cost) { - tem = expand_binop (wider_mode, moptab, op0, op1, 0, + rtx insns, wop0, wop1; + + /* We need to widen the operands, for example to ensure the + constant multiplier is correctly sign or zero extended. + Use a sequence to clean-up any instructions emitted by + the conversions if things don't work out. */ + start_sequence (); + wop0 = convert_modes (wider_mode, mode, op0, unsignedp); + wop1 = convert_modes (wider_mode, mode, op1, unsignedp); + tem = expand_binop (wider_mode, smul_optab, wop0, wop1, 0, unsignedp, OPTAB_WIDEN); + insns = get_insns (); + end_sequence (); + if (tem) - return extract_high_half (mode, tem); + { + emit_insn (insns); + return extract_high_half (mode, tem); + } } /* Try widening multiplication of opposite signedness, and adjust. */