diff options
author | Roger Sayle <roger@eyesopen.com> | 2005-01-28 17:49:47 +0000 |
---|---|---|
committer | Roger Sayle <sayle@gcc.gnu.org> | 2005-01-28 17:49:47 +0000 |
commit | 82dfb9a58fa7f797c1a9e49708fe9ed273ba4f70 (patch) | |
tree | 9f7f74daa83e42167de74f75541257536cd7de0b | |
parent | 6aea8136e22b50b779c6a59e10a8b4f583513e61 (diff) | |
download | gcc-82dfb9a58fa7f797c1a9e49708fe9ed273ba4f70.zip gcc-82dfb9a58fa7f797c1a9e49708fe9ed273ba4f70.tar.gz gcc-82dfb9a58fa7f797c1a9e49708fe9ed273ba4f70.tar.bz2 |
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
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/expmed.c | 20 |
2 files changed, 23 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 97410c0..08fc4c2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2005-01-28 Roger Sayle <roger@eyesopen.com> + + * 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 <ian@airs.com> PR middle-end/16558 diff --git a/gcc/expmed.c b/gcc/expmed.c index 1091c45..87a219d 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. */ |