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
This commit is contained in:
parent
e1514303f2
commit
1c234fcb72
2 changed files with 42 additions and 11 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
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.
|
||||||
|
|
31
gcc/expmed.c
31
gcc/expmed.c
|
@ -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)
|
||||||
if (signmask)
|
if (signmask)
|
||||||
{
|
{
|
||||||
signmask = force_reg (mode, signmask);
|
signmask = force_reg (mode, signmask);
|
||||||
|
mask = ((HOST_WIDE_INT) 1 << logd) - 1;
|
||||||
|
shift = GEN_INT (GET_MODE_BITSIZE (mode) - logd);
|
||||||
|
|
||||||
|
/* Use the rtx_cost of a LSHIFTRT instruction to determine
|
||||||
|
which instruction sequence to use. If logical right shifts
|
||||||
|
are expensive the use 2 XORs, 2 SUBs and an AND, otherwise
|
||||||
|
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,
|
temp = expand_binop (mode, xor_optab, op0, signmask,
|
||||||
NULL_RTX, 1, OPTAB_LIB_WIDEN);
|
NULL_RTX, 1, OPTAB_LIB_WIDEN);
|
||||||
temp = expand_binop (mode, sub_optab, temp, signmask,
|
temp = expand_binop (mode, sub_optab, temp, signmask,
|
||||||
NULL_RTX, 0, OPTAB_LIB_WIDEN);
|
NULL_RTX, 1, OPTAB_LIB_WIDEN);
|
||||||
mask = ((HOST_WIDE_INT) 1 << logd) - 1;
|
|
||||||
temp = expand_binop (mode, and_optab, temp, GEN_INT (mask),
|
temp = expand_binop (mode, and_optab, temp, GEN_INT (mask),
|
||||||
NULL_RTX, 1, OPTAB_LIB_WIDEN);
|
NULL_RTX, 1, OPTAB_LIB_WIDEN);
|
||||||
temp = expand_binop (mode, xor_optab, temp, signmask,
|
temp = expand_binop (mode, xor_optab, temp, signmask,
|
||||||
NULL_RTX, 1, OPTAB_LIB_WIDEN);
|
NULL_RTX, 1, OPTAB_LIB_WIDEN);
|
||||||
temp = expand_binop (mode, sub_optab, temp, signmask,
|
temp = expand_binop (mode, sub_optab, temp, signmask,
|
||||||
NULL_RTX, 1, OPTAB_LIB_WIDEN);
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue