aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoger Sayle <roger@eyesopen.com>2005-01-28 17:49:47 +0000
committerRoger Sayle <sayle@gcc.gnu.org>2005-01-28 17:49:47 +0000
commit82dfb9a58fa7f797c1a9e49708fe9ed273ba4f70 (patch)
tree9f7f74daa83e42167de74f75541257536cd7de0b
parent6aea8136e22b50b779c6a59e10a8b4f583513e61 (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/expmed.c20
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. */