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
This commit is contained in:
Roger Sayle 2005-01-28 17:49:47 +00:00 committed by Roger Sayle
parent 6aea8136e2
commit 82dfb9a58f
2 changed files with 23 additions and 3 deletions

View File

@ -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

View File

@ -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. */