summaryrefslogtreecommitdiff
path: root/gcc/expmed.c
diff options
context:
space:
mode:
authorsayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>2005-01-28 17:49:47 +0000
committersayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>2005-01-28 17:49:47 +0000
commit857a11763caf6d43ab8b513dca76c81805777ccf (patch)
tree9f7f74daa83e42167de74f75541257536cd7de0b /gcc/expmed.c
parentb2e26ec355ffbb0ea38a1fa7638f38788cdcf309 (diff)
downloadgcc-857a11763caf6d43ab8b513dca76c81805777ccf.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@94383 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/expmed.c')
-rw-r--r--gcc/expmed.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/gcc/expmed.c b/gcc/expmed.c
index 1091c454064..87a219d2605 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. */