mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1027359 - Fix incorrect codegen in ma_mod_mask. (r=mjrosenb)
This commit is contained in:
parent
1fd6574e68
commit
e5d1fe8bee
@ -826,9 +826,10 @@ CodeGeneratorARM::visitModMaskI(LModMaskI *ins)
|
||||
{
|
||||
Register src = ToRegister(ins->getOperand(0));
|
||||
Register dest = ToRegister(ins->getDef(0));
|
||||
Register tmp = ToRegister(ins->getTemp(0));
|
||||
Register tmp1 = ToRegister(ins->getTemp(0));
|
||||
Register tmp2 = ToRegister(ins->getTemp(1));
|
||||
MMod *mir = ins->mir();
|
||||
masm.ma_mod_mask(src, dest, tmp, ins->shift());
|
||||
masm.ma_mod_mask(src, dest, tmp1, tmp2, ins->shift());
|
||||
if (mir->canBeNegativeDividend()) {
|
||||
if (!mir->isTruncated()) {
|
||||
JS_ASSERT(mir->fallible());
|
||||
|
@ -263,18 +263,20 @@ class LModPowTwoI : public LInstructionHelper<1, 1, 0>
|
||||
}
|
||||
};
|
||||
|
||||
class LModMaskI : public LInstructionHelper<1, 1, 1>
|
||||
class LModMaskI : public LInstructionHelper<1, 1, 2>
|
||||
{
|
||||
const int32_t shift_;
|
||||
|
||||
public:
|
||||
LIR_HEADER(ModMaskI);
|
||||
|
||||
LModMaskI(const LAllocation &lhs, const LDefinition &temp1, int32_t shift)
|
||||
LModMaskI(const LAllocation &lhs, const LDefinition &temp1, const LDefinition &temp2,
|
||||
int32_t shift)
|
||||
: shift_(shift)
|
||||
{
|
||||
setOperand(0, lhs);
|
||||
setTemp(0, temp1);
|
||||
setTemp(1, temp2);
|
||||
}
|
||||
|
||||
int32_t shift() const {
|
||||
|
@ -321,7 +321,7 @@ LIRGeneratorARM::lowerModI(MMod *mod)
|
||||
return false;
|
||||
return define(lir, mod);
|
||||
} else if (shift < 31 && (1 << (shift+1)) - 1 == rhs) {
|
||||
LModMaskI *lir = new(alloc()) LModMaskI(useRegister(mod->lhs()), temp(LDefinition::GENERAL), shift+1);
|
||||
LModMaskI *lir = new(alloc()) LModMaskI(useRegister(mod->lhs()), temp(), temp(), shift+1);
|
||||
if (mod->fallible() && !assignSnapshot(lir, Bailout_DoubleOutput))
|
||||
return false;
|
||||
return define(lir, mod);
|
||||
|
@ -922,7 +922,8 @@ MacroAssemblerARM::ma_check_mul(Register src1, Imm32 imm, Register dest, Conditi
|
||||
}
|
||||
|
||||
void
|
||||
MacroAssemblerARM::ma_mod_mask(Register src, Register dest, Register hold, int32_t shift)
|
||||
MacroAssemblerARM::ma_mod_mask(Register src, Register dest, Register hold, Register tmp,
|
||||
int32_t shift)
|
||||
{
|
||||
// MATH:
|
||||
// We wish to compute x % (1<<y) - 1 for a known constant, y.
|
||||
@ -945,20 +946,24 @@ MacroAssemblerARM::ma_mod_mask(Register src, Register dest, Register hold, int32
|
||||
// as holding the trial subtraction as a temp value
|
||||
// dest is the accumulator (and holds the final result)
|
||||
|
||||
// move the whole value into the scratch register, setting the codition codes so
|
||||
// we can muck with them later
|
||||
as_mov(ScratchRegister, O2Reg(src), SetCond);
|
||||
// move the whole value into tmp, setting the codition codes so we can
|
||||
// muck with them later.
|
||||
//
|
||||
// Note that we cannot use ScratchRegister in place of tmp here, as ma_and
|
||||
// below on certain architectures move the mask into ScratchRegister
|
||||
// before performing the bitwise and.
|
||||
as_mov(tmp, O2Reg(src), SetCond);
|
||||
// Zero out the dest.
|
||||
ma_mov(Imm32(0), dest);
|
||||
// Set the hold appropriately.
|
||||
ma_mov(Imm32(1), hold);
|
||||
ma_mov(Imm32(-1), hold, NoSetCond, Signed);
|
||||
ma_rsb(Imm32(0), ScratchRegister, SetCond, Signed);
|
||||
ma_rsb(Imm32(0), tmp, SetCond, Signed);
|
||||
// Begin the main loop.
|
||||
bind(&head);
|
||||
|
||||
// Extract the bottom bits into lr.
|
||||
ma_and(Imm32(mask), ScratchRegister, secondScratchReg_);
|
||||
ma_and(Imm32(mask), tmp, secondScratchReg_);
|
||||
// Add those bits to the accumulator.
|
||||
ma_add(secondScratchReg_, dest, dest);
|
||||
// Do a trial subtraction, this is the same operation as cmp, but we store the dest
|
||||
@ -966,7 +971,7 @@ MacroAssemblerARM::ma_mod_mask(Register src, Register dest, Register hold, int32
|
||||
// If (sum - C) > 0, store sum - C back into sum, thus performing a modulus.
|
||||
ma_mov(secondScratchReg_, dest, NoSetCond, NotSigned);
|
||||
// Get rid of the bits that we extracted before, and set the condition codes
|
||||
as_mov(ScratchRegister, lsr(ScratchRegister, shift), SetCond);
|
||||
as_mov(tmp, lsr(tmp, shift), SetCond);
|
||||
// If the shift produced zero, finish, otherwise, continue in the loop.
|
||||
ma_b(&head, NonZero);
|
||||
// Check the hold to see if we need to negate the result. Hold can only be 1 or -1,
|
||||
|
@ -263,7 +263,8 @@ class MacroAssemblerARM : public Assembler
|
||||
|
||||
// fast mod, uses scratch registers, and thus needs to be in the assembler
|
||||
// implicitly assumes that we can overwrite dest at the beginning of the sequence
|
||||
void ma_mod_mask(Register src, Register dest, Register hold, int32_t shift);
|
||||
void ma_mod_mask(Register src, Register dest, Register hold, Register tmp,
|
||||
int32_t shift);
|
||||
|
||||
// mod, depends on integer divide instructions being supported
|
||||
void ma_smod(Register num, Register div, Register dest);
|
||||
|
Loading…
Reference in New Issue
Block a user