Commit 1c234fcb by Roger Sayle Committed by Roger Sayle

expmed.c (expand_smod_pow2): Provide alternate implementations that avoid conditional jumps...


	* expmed.c (expand_smod_pow2): Provide alternate implementations
	that avoid conditional jumps, and choose between them based upon
	the target's rtx_costs.

From-SVN: r83861
parent e1514303
2004-06-29 Roger Sayle <roger@eyesopen.com>
* expmed.c (expand_smod_pow2): Provide alternate implementations
that avoid conditional jumps, and choose between them based upon
the target's rtx_costs.
2004-06-29 Andrew Pinski <apinski@apple.com> 2004-06-29 Andrew Pinski <apinski@apple.com>
* tree-sra.c: Include expr.h for definition of MOVE_RATIO. * tree-sra.c: Include expr.h for definition of MOVE_RATIO.
......
...@@ -3064,7 +3064,7 @@ static rtx ...@@ -3064,7 +3064,7 @@ static rtx
expand_smod_pow2 (enum machine_mode mode, rtx op0, HOST_WIDE_INT d) expand_smod_pow2 (enum machine_mode mode, rtx op0, HOST_WIDE_INT d)
{ {
unsigned HOST_WIDE_INT mask; unsigned HOST_WIDE_INT mask;
rtx result, temp, label; rtx result, temp, shift, label;
int logd; int logd;
logd = floor_log2 (d); logd = floor_log2 (d);
...@@ -3079,17 +3079,42 @@ expand_smod_pow2 (enum machine_mode mode, rtx op0, HOST_WIDE_INT d) ...@@ -3079,17 +3079,42 @@ expand_smod_pow2 (enum machine_mode mode, rtx op0, HOST_WIDE_INT d)
if (signmask) if (signmask)
{ {
signmask = force_reg (mode, signmask); signmask = force_reg (mode, signmask);
temp = expand_binop (mode, xor_optab, op0, signmask,
NULL_RTX, 1, OPTAB_LIB_WIDEN);
temp = expand_binop (mode, sub_optab, temp, signmask,
NULL_RTX, 0, OPTAB_LIB_WIDEN);
mask = ((HOST_WIDE_INT) 1 << logd) - 1; mask = ((HOST_WIDE_INT) 1 << logd) - 1;
temp = expand_binop (mode, and_optab, temp, GEN_INT (mask), shift = GEN_INT (GET_MODE_BITSIZE (mode) - logd);
NULL_RTX, 1, OPTAB_LIB_WIDEN);
temp = expand_binop (mode, xor_optab, temp, signmask, /* Use the rtx_cost of a LSHIFTRT instruction to determine
NULL_RTX, 1, OPTAB_LIB_WIDEN); which instruction sequence to use. If logical right shifts
temp = expand_binop (mode, sub_optab, temp, signmask, are expensive the use 2 XORs, 2 SUBs and an AND, otherwise
NULL_RTX, 1, OPTAB_LIB_WIDEN); use a LSHIFTRT, 1 ADD, 1 SUB and an AND. */
temp = gen_rtx_LSHIFTRT (mode, result, shift);
if (lshr_optab->handlers[mode].insn_code == CODE_FOR_nothing
|| rtx_cost (temp, SET) > COSTS_N_INSNS (2))
{
temp = expand_binop (mode, xor_optab, op0, signmask,
NULL_RTX, 1, OPTAB_LIB_WIDEN);
temp = expand_binop (mode, sub_optab, temp, signmask,
NULL_RTX, 1, OPTAB_LIB_WIDEN);
temp = expand_binop (mode, and_optab, temp, GEN_INT (mask),
NULL_RTX, 1, OPTAB_LIB_WIDEN);
temp = expand_binop (mode, xor_optab, temp, signmask,
NULL_RTX, 1, OPTAB_LIB_WIDEN);
temp = expand_binop (mode, sub_optab, temp, signmask,
NULL_RTX, 1, OPTAB_LIB_WIDEN);
}
else
{
signmask = expand_binop (mode, lshr_optab, signmask, shift,
NULL_RTX, 1, OPTAB_LIB_WIDEN);
signmask = force_reg (mode, signmask);
temp = expand_binop (mode, add_optab, op0, signmask,
NULL_RTX, 1, OPTAB_LIB_WIDEN);
temp = expand_binop (mode, and_optab, temp, GEN_INT (mask),
NULL_RTX, 1, OPTAB_LIB_WIDEN);
temp = expand_binop (mode, sub_optab, temp, signmask,
NULL_RTX, 1, OPTAB_LIB_WIDEN);
}
return temp; return temp;
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment