aboutsummaryrefslogtreecommitdiff
path: root/gcc/expmed.c
diff options
context:
space:
mode:
authorTorbjorn Granlund <tege@gnu.org>1995-12-17 16:41:09 +0000
committerTorbjorn Granlund <tege@gnu.org>1995-12-17 16:41:09 +0000
commita295d3317e3675c09de2b101e88f08eba04f26c5 (patch)
treedfc0501c8c3289e36915d365c7c21566acbff48e /gcc/expmed.c
parentb10af0c8206f7ff2aefd13b3d7d20accf4c9a33c (diff)
downloadgcc-a295d3317e3675c09de2b101e88f08eba04f26c5.zip
gcc-a295d3317e3675c09de2b101e88f08eba04f26c5.tar.gz
gcc-a295d3317e3675c09de2b101e88f08eba04f26c5.tar.bz2
(expand_mult_highpart): When doing widening multiply,
put constant in a register. (expand_mult_highpart): When mode is word_mode use gen_highpart instead of right shift by size. From-SVN: r10789
Diffstat (limited to 'gcc/expmed.c')
-rw-r--r--gcc/expmed.c28
1 files changed, 21 insertions, 7 deletions
diff --git a/gcc/expmed.c b/gcc/expmed.c
index 3c74e47..384ede4 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -2610,13 +2610,19 @@ expand_mult_highpart (mode, op0, cnst1, target, unsignedp, max_cost)
moptab = unsignedp ? umul_widen_optab : smul_widen_optab;
if (moptab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
&& mul_widen_cost[(int) wider_mode] < max_cost)
- goto try;
+ {
+ op1 = force_reg (mode, op1);
+ goto try;
+ }
/* Try widening the mode and perform a non-widening multiplication. */
moptab = smul_optab;
if (smul_optab->handlers[(int) wider_mode].insn_code != CODE_FOR_nothing
&& mul_cost[(int) wider_mode] + shift_cost[size-1] < max_cost)
- goto try;
+ {
+ op1 = wide_op1;
+ goto try;
+ }
/* Try widening multiplication of opposite signedness, and adjust. */
moptab = unsignedp ? smul_widen_optab : umul_widen_optab;
@@ -2624,7 +2630,8 @@ expand_mult_highpart (mode, op0, cnst1, target, unsignedp, max_cost)
&& (mul_widen_cost[(int) wider_mode]
+ 2 * shift_cost[size-1] + 4 * add_cost < max_cost))
{
- tem = expand_binop (wider_mode, moptab, op0, wide_op1,
+ rtx regop1 = force_reg (mode, op1);
+ tem = expand_binop (wider_mode, moptab, op0, regop1,
NULL_RTX, ! unsignedp, OPTAB_WIDEN);
if (tem != 0)
{
@@ -2642,15 +2649,22 @@ expand_mult_highpart (mode, op0, cnst1, target, unsignedp, max_cost)
try:
/* Pass NULL_RTX as target since TARGET has wrong mode. */
- tem = expand_binop (wider_mode, moptab, op0, wide_op1,
+ tem = expand_binop (wider_mode, moptab, op0, op1,
NULL_RTX, unsignedp, OPTAB_WIDEN);
if (tem == 0)
return 0;
/* Extract the high half of the just generated product. */
- tem = expand_shift (RSHIFT_EXPR, wider_mode, tem,
- build_int_2 (size, 0), NULL_RTX, 1);
- return convert_modes (mode, wider_mode, tem, unsignedp);
+ if (mode == word_mode)
+ {
+ return gen_highpart (mode, tem);
+ }
+ else
+ {
+ tem = expand_shift (RSHIFT_EXPR, wider_mode, tem,
+ build_int_2 (size, 0), NULL_RTX, 1);
+ return convert_modes (mode, wider_mode, tem, unsignedp);
+ }
}
/* Emit the code to divide OP0 by OP1, putting the result in TARGET