diff options
author | Torbjorn Granlund <tege@gnu.org> | 1995-12-17 16:41:09 +0000 |
---|---|---|
committer | Torbjorn Granlund <tege@gnu.org> | 1995-12-17 16:41:09 +0000 |
commit | a295d3317e3675c09de2b101e88f08eba04f26c5 (patch) | |
tree | dfc0501c8c3289e36915d365c7c21566acbff48e /gcc | |
parent | b10af0c8206f7ff2aefd13b3d7d20accf4c9a33c (diff) | |
download | gcc-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')
-rw-r--r-- | gcc/expmed.c | 28 |
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 |