mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-19 00:05:36 +00:00
Bug 1428453 - Baldr: use new traps for idiv (r=bbouvier)
--HG-- extra : rebase_source : 530b9de9df9dfab1a3db688156c04d1c97cc9158
This commit is contained in:
parent
3c79523451
commit
363c35ecbf
@ -554,7 +554,10 @@ CodeGeneratorARM::divICommon(MDiv* mir, Register lhs, Register rhs, Register out
|
||||
masm.as_cmp(rhs, Imm8(0));
|
||||
if (mir->canTruncateInfinities()) {
|
||||
if (mir->trapOnError()) {
|
||||
masm.ma_b(oldTrap(mir, wasm::Trap::IntegerDivideByZero), Assembler::Equal);
|
||||
Label nonZero;
|
||||
masm.ma_b(&nonZero, Assembler::NotEqual);
|
||||
masm.wasmTrap(wasm::Trap::IntegerDivideByZero, mir->bytecodeOffset());
|
||||
masm.bind(&nonZero);
|
||||
} else {
|
||||
// Infinity|0 == 0
|
||||
Label skip;
|
||||
@ -717,7 +720,10 @@ CodeGeneratorARM::modICommon(MMod* mir, Register lhs, Register rhs, Register out
|
||||
// wasm allows negative lhs and return 0 in this case.
|
||||
MOZ_ASSERT(mir->isTruncated());
|
||||
masm.as_cmp(rhs, Imm8(0));
|
||||
masm.ma_b(oldTrap(mir, wasm::Trap::IntegerDivideByZero), Assembler::Equal);
|
||||
Label nonZero;
|
||||
masm.ma_b(&nonZero, Assembler::NotEqual);
|
||||
masm.wasmTrap(wasm::Trap::IntegerDivideByZero, mir->bytecodeOffset());
|
||||
masm.bind(&nonZero);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2420,7 +2426,10 @@ CodeGeneratorARM::generateUDivModZeroCheck(Register rhs, Register output, Label*
|
||||
masm.as_cmp(rhs, Imm8(0));
|
||||
if (mir->isTruncated()) {
|
||||
if (mir->trapOnError()) {
|
||||
masm.ma_b(oldTrap(mir, wasm::Trap::IntegerDivideByZero), Assembler::Equal);
|
||||
Label nonZero;
|
||||
masm.ma_b(&nonZero, Assembler::NotEqual);
|
||||
masm.wasmTrap(wasm::Trap::IntegerDivideByZero, mir->bytecodeOffset());
|
||||
masm.bind(&nonZero);
|
||||
} else {
|
||||
Label skip;
|
||||
masm.ma_b(&skip, Assembler::NotEqual);
|
||||
@ -2770,8 +2779,10 @@ CodeGeneratorARM::visitDivOrModI64(LDivOrModI64* lir)
|
||||
// Handle divide by zero.
|
||||
if (lir->canBeDivideByZero()) {
|
||||
Register temp = WasmGetTemporaryForDivOrMod(lhs, rhs);
|
||||
masm.branchTest64(Assembler::Zero, rhs, rhs, temp,
|
||||
oldTrap(lir, wasm::Trap::IntegerDivideByZero));
|
||||
Label nonZero;
|
||||
masm.branchTest64(Assembler::NonZero, rhs, rhs, temp, &nonZero);
|
||||
masm.wasmTrap(wasm::Trap::IntegerDivideByZero, lir->bytecodeOffset());
|
||||
masm.bind(&nonZero);
|
||||
}
|
||||
|
||||
auto* mir = lir->mir();
|
||||
@ -2816,8 +2827,10 @@ CodeGeneratorARM::visitUDivOrModI64(LUDivOrModI64* lir)
|
||||
// Prevent divide by zero.
|
||||
if (lir->canBeDivideByZero()) {
|
||||
Register temp = WasmGetTemporaryForDivOrMod(lhs, rhs);
|
||||
masm.branchTest64(Assembler::Zero, rhs, rhs, temp,
|
||||
oldTrap(lir, wasm::Trap::IntegerDivideByZero));
|
||||
Label nonZero;
|
||||
masm.branchTest64(Assembler::NonZero, rhs, rhs, temp, &nonZero);
|
||||
masm.wasmTrap(wasm::Trap::IntegerDivideByZero, lir->bytecodeOffset());
|
||||
masm.bind(&nonZero);
|
||||
}
|
||||
|
||||
masm.setupWasmABICall();
|
||||
|
@ -1725,7 +1725,7 @@ MacroAssembler::branchTest64(Condition cond, Register64 lhs, Register64 rhs, Reg
|
||||
{
|
||||
ScratchRegisterScope scratch(*this);
|
||||
|
||||
if (cond == Assembler::Zero) {
|
||||
if (cond == Assembler::Zero || cond == Assembler::NonZero) {
|
||||
MOZ_ASSERT(lhs.low == rhs.low);
|
||||
MOZ_ASSERT(lhs.high == rhs.high);
|
||||
ma_orr(lhs.low, lhs.high, scratch);
|
||||
|
@ -568,7 +568,10 @@ CodeGeneratorMIPSShared::visitDivI(LDivI* ins)
|
||||
// Handle divide by zero.
|
||||
if (mir->canBeDivideByZero()) {
|
||||
if (mir->trapOnError()) {
|
||||
masm.ma_b(rhs, rhs, oldTrap(mir, wasm::Trap::IntegerDivideByZero), Assembler::Zero);
|
||||
Label nonZero;
|
||||
masm.ma_b(rhs, rhs, &nonZero, Assembler::NonZero);
|
||||
masm.wasmTrap(wasm::Trap::IntegerDivideByZero, mir->bytecodeOffset());
|
||||
masm.bind(&nonZero);
|
||||
} else if (mir->canTruncateInfinities()) {
|
||||
// Truncated division by zero is zero (Infinity|0 == 0)
|
||||
Label notzero;
|
||||
@ -721,7 +724,10 @@ CodeGeneratorMIPSShared::visitModI(LModI* ins)
|
||||
if (mir->canBeDivideByZero()) {
|
||||
if (mir->isTruncated()) {
|
||||
if (mir->trapOnError()) {
|
||||
masm.ma_b(rhs, rhs, oldTrap(mir, wasm::Trap::IntegerDivideByZero), Assembler::Zero);
|
||||
Label nonZero;
|
||||
masm.ma_b(rhs, rhs, &nonZero, Assembler::NonZero);
|
||||
masm.wasmTrap(wasm::Trap::IntegerDivideByZero, mir->bytecodeOffset());
|
||||
masm.bind(&nonZero);
|
||||
} else {
|
||||
Label skip;
|
||||
masm.ma_b(rhs, Imm32(0), &skip, Assembler::NotEqual, ShortJump);
|
||||
@ -2395,7 +2401,10 @@ CodeGeneratorMIPSShared::visitUDivOrMod(LUDivOrMod* ins)
|
||||
if (ins->canBeDivideByZero()) {
|
||||
if (ins->mir()->isTruncated()) {
|
||||
if (ins->trapOnError()) {
|
||||
masm.ma_b(rhs, rhs, oldTrap(ins, wasm::Trap::IntegerDivideByZero), Assembler::Zero);
|
||||
Label nonZero;
|
||||
masm.ma_b(rhs, rhs, &nonZero, Assembler::NonZero);
|
||||
masm.wasmTrap(wasm::Trap::IntegerDivideByZero, ins->bytecodeOffset());
|
||||
masm.bind(&nonZero)
|
||||
} else {
|
||||
// Infinity|0 == 0
|
||||
Label notzero;
|
||||
|
@ -379,8 +379,12 @@ CodeGeneratorMIPS::visitDivOrModI64(LDivOrModI64* lir)
|
||||
Label done;
|
||||
|
||||
// Handle divide by zero.
|
||||
if (lir->canBeDivideByZero())
|
||||
masm.branchTest64(Assembler::Zero, rhs, rhs, temp, oldTrap(lir, wasm::Trap::IntegerDivideByZero));
|
||||
if (lir->canBeDivideByZero()) {
|
||||
Label nonZero;
|
||||
masm.branchTest64(Assembler::NonZero, rhs, rhs, temp, &nonZero);
|
||||
masm.wasmTrap(wasm::Trap::IntegerDivideByZero, lir->bytecodeOffset());
|
||||
masm.bind(&nonZero);
|
||||
}
|
||||
|
||||
// Handle an integer overflow exception from INT64_MIN / -1.
|
||||
if (lir->canBeNegativeOverflow()) {
|
||||
@ -431,8 +435,12 @@ CodeGeneratorMIPS::visitUDivOrModI64(LUDivOrModI64* lir)
|
||||
Register temp = regs.takeAny();
|
||||
|
||||
// Prevent divide by zero.
|
||||
if (lir->canBeDivideByZero())
|
||||
masm.branchTest64(Assembler::Zero, rhs, rhs, temp, oldTrap(lir, wasm::Trap::IntegerDivideByZero));
|
||||
if (lir->canBeDivideByZero()) {
|
||||
Label nonZero;
|
||||
masm.branchTest64(Assembler::NonZero, rhs, rhs, temp, &nonZero);
|
||||
masm.wasmTrap(wasm::Trap::IntegerDivideByZero, lir->bytecodeOffset());
|
||||
masm.bind(&nonZero);
|
||||
}
|
||||
|
||||
masm.setupWasmABICall();
|
||||
masm.passABIArg(lhs.high);
|
||||
|
@ -361,8 +361,12 @@ CodeGeneratorMIPS64::visitDivOrModI64(LDivOrModI64* lir)
|
||||
Label done;
|
||||
|
||||
// Handle divide by zero.
|
||||
if (lir->canBeDivideByZero())
|
||||
masm.ma_b(rhs, rhs, oldTrap(lir, wasm::Trap::IntegerDivideByZero), Assembler::Zero);
|
||||
if (lir->canBeDivideByZero()) {
|
||||
Label nonZero;
|
||||
masm.ma_b(rhs, rhs, &nonZero, Assembler::NonZero);
|
||||
masm.wasmTrap(wasm::Trap::IntegerDivideByZero, lir->bytecodeOffset());
|
||||
masm.bind(&nonZero);
|
||||
}
|
||||
|
||||
// Handle an integer overflow exception from INT64_MIN / -1.
|
||||
if (lir->canBeNegativeOverflow()) {
|
||||
@ -397,8 +401,12 @@ CodeGeneratorMIPS64::visitUDivOrModI64(LUDivOrModI64* lir)
|
||||
Label done;
|
||||
|
||||
// Prevent divide by zero.
|
||||
if (lir->canBeDivideByZero())
|
||||
masm.ma_b(rhs, rhs, oldTrap(lir, wasm::Trap::IntegerDivideByZero), Assembler::Zero);
|
||||
if (lir->canBeDivideByZero()) {
|
||||
Label nonZero;
|
||||
masm.ma_b(rhs, rhs, &nonZero, Assembler::NonZero);
|
||||
masm.wasmTrap(wasm::Trap::IntegerDivideByZero, lir->bytecodeOffset());
|
||||
masm.bind(&nonZero);
|
||||
}
|
||||
|
||||
masm.as_ddivu(lhs, rhs);
|
||||
|
||||
|
@ -285,7 +285,10 @@ CodeGeneratorX64::visitDivOrModI64(LDivOrModI64* lir)
|
||||
|
||||
// Handle divide by zero.
|
||||
if (lir->canBeDivideByZero()) {
|
||||
masm.branchTestPtr(Assembler::Zero, rhs, rhs, oldTrap(lir, wasm::Trap::IntegerDivideByZero));
|
||||
Label nonZero;
|
||||
masm.branchTestPtr(Assembler::NonZero, rhs, rhs, &nonZero);
|
||||
masm.wasmTrap(wasm::Trap::IntegerDivideByZero, lir->bytecodeOffset());
|
||||
masm.bind(&nonZero);
|
||||
}
|
||||
|
||||
// Handle an integer overflow exception from INT64_MIN / -1.
|
||||
@ -327,8 +330,12 @@ CodeGeneratorX64::visitUDivOrModI64(LUDivOrModI64* lir)
|
||||
Label done;
|
||||
|
||||
// Prevent divide by zero.
|
||||
if (lir->canBeDivideByZero())
|
||||
masm.branchTestPtr(Assembler::Zero, rhs, rhs, oldTrap(lir, wasm::Trap::IntegerDivideByZero));
|
||||
if (lir->canBeDivideByZero()) {
|
||||
Label nonZero;
|
||||
masm.branchTestPtr(Assembler::NonZero, rhs, rhs, &nonZero);
|
||||
masm.wasmTrap(wasm::Trap::IntegerDivideByZero, lir->bytecodeOffset());
|
||||
masm.bind(&nonZero);
|
||||
}
|
||||
|
||||
// Zero extend the lhs into rdx to make (rdx:rax).
|
||||
masm.xorl(rdx, rdx);
|
||||
|
@ -1026,7 +1026,10 @@ CodeGeneratorX86Shared::visitUDivOrMod(LUDivOrMod* ins)
|
||||
masm.test32(rhs, rhs);
|
||||
if (ins->mir()->isTruncated()) {
|
||||
if (ins->trapOnError()) {
|
||||
masm.j(Assembler::Zero, oldTrap(ins, wasm::Trap::IntegerDivideByZero));
|
||||
Label nonZero;
|
||||
masm.j(Assembler::NonZero, &nonZero);
|
||||
masm.wasmTrap(wasm::Trap::IntegerDivideByZero, ins->bytecodeOffset());
|
||||
masm.bind(&nonZero);
|
||||
} else {
|
||||
ool = new(alloc()) ReturnZero(output);
|
||||
masm.j(Assembler::Zero, ool->entry());
|
||||
@ -1074,7 +1077,7 @@ CodeGeneratorX86Shared::visitUDivOrModConstant(LUDivOrModConstant *ins) {
|
||||
if (d == 0) {
|
||||
if (ins->mir()->isTruncated()) {
|
||||
if (ins->trapOnError())
|
||||
masm.jump(oldTrap(ins, wasm::Trap::IntegerDivideByZero));
|
||||
masm.wasmTrap(wasm::Trap::IntegerDivideByZero, ins->bytecodeOffset());
|
||||
else
|
||||
masm.xorl(output, output);
|
||||
} else {
|
||||
@ -1336,7 +1339,10 @@ CodeGeneratorX86Shared::visitDivI(LDivI* ins)
|
||||
if (mir->canBeDivideByZero()) {
|
||||
masm.test32(rhs, rhs);
|
||||
if (mir->trapOnError()) {
|
||||
masm.j(Assembler::Zero, oldTrap(mir, wasm::Trap::IntegerDivideByZero));
|
||||
Label nonZero;
|
||||
masm.j(Assembler::NonZero, &nonZero);
|
||||
masm.wasmTrap(wasm::Trap::IntegerDivideByZero, mir->bytecodeOffset());
|
||||
masm.bind(&nonZero);
|
||||
} else if (mir->canTruncateInfinities()) {
|
||||
// Truncated division by zero is zero (Infinity|0 == 0)
|
||||
if (!ool)
|
||||
@ -1506,7 +1512,10 @@ CodeGeneratorX86Shared::visitModI(LModI* ins)
|
||||
masm.test32(rhs, rhs);
|
||||
if (mir->isTruncated()) {
|
||||
if (mir->trapOnError()) {
|
||||
masm.j(Assembler::Zero, oldTrap(mir, wasm::Trap::IntegerDivideByZero));
|
||||
Label nonZero;
|
||||
masm.j(Assembler::NonZero, &nonZero);
|
||||
masm.wasmTrap(wasm::Trap::IntegerDivideByZero, mir->bytecodeOffset());
|
||||
masm.bind(&nonZero);
|
||||
} else {
|
||||
if (!ool)
|
||||
ool = new(alloc()) ReturnZero(edx);
|
||||
|
@ -1038,8 +1038,12 @@ CodeGeneratorX86::visitDivOrModI64(LDivOrModI64* lir)
|
||||
Label done;
|
||||
|
||||
// Handle divide by zero.
|
||||
if (lir->canBeDivideByZero())
|
||||
masm.branchTest64(Assembler::Zero, rhs, rhs, temp, oldTrap(lir, wasm::Trap::IntegerDivideByZero));
|
||||
if (lir->canBeDivideByZero()) {
|
||||
Label nonZero;
|
||||
masm.branchTest64(Assembler::NonZero, rhs, rhs, temp, &nonZero);
|
||||
masm.wasmTrap(wasm::Trap::IntegerDivideByZero, lir->bytecodeOffset());
|
||||
masm.bind(&nonZero);
|
||||
}
|
||||
|
||||
MDefinition* mir = lir->mir();
|
||||
|
||||
@ -1086,8 +1090,12 @@ CodeGeneratorX86::visitUDivOrModI64(LUDivOrModI64* lir)
|
||||
MOZ_ASSERT(output == ReturnReg64);
|
||||
|
||||
// Prevent divide by zero.
|
||||
if (lir->canBeDivideByZero())
|
||||
masm.branchTest64(Assembler::Zero, rhs, rhs, temp, oldTrap(lir, wasm::Trap::IntegerDivideByZero));
|
||||
if (lir->canBeDivideByZero()) {
|
||||
Label nonZero;
|
||||
masm.branchTest64(Assembler::NonZero, rhs, rhs, temp, &nonZero);
|
||||
masm.wasmTrap(wasm::Trap::IntegerDivideByZero, lir->bytecodeOffset());
|
||||
masm.bind(&nonZero);
|
||||
}
|
||||
|
||||
masm.setupWasmABICall();
|
||||
masm.passABIArg(lhs.high);
|
||||
|
@ -970,7 +970,7 @@ void
|
||||
MacroAssembler::branchTest64(Condition cond, Register64 lhs, Register64 rhs, Register temp,
|
||||
L label)
|
||||
{
|
||||
if (cond == Assembler::Zero) {
|
||||
if (cond == Assembler::Zero || cond == Assembler::NonZero) {
|
||||
MOZ_ASSERT(lhs.low == rhs.low);
|
||||
MOZ_ASSERT(lhs.high == rhs.high);
|
||||
movl(lhs.low, temp);
|
||||
|
@ -3440,12 +3440,18 @@ class BaseCompiler final : public BaseCompilerInterface
|
||||
}
|
||||
|
||||
void checkDivideByZeroI32(RegI32 rhs, RegI32 srcDest, Label* done) {
|
||||
masm.branchTest32(Assembler::Zero, rhs, rhs, oldTrap(Trap::IntegerDivideByZero));
|
||||
Label nonZero;
|
||||
masm.branchTest32(Assembler::NonZero, rhs, rhs, &nonZero);
|
||||
trap(Trap::IntegerDivideByZero);
|
||||
masm.bind(&nonZero);
|
||||
}
|
||||
|
||||
void checkDivideByZeroI64(RegI64 r) {
|
||||
Label nonZero;
|
||||
ScratchI32 scratch(*this);
|
||||
masm.branchTest64(Assembler::Zero, r, r, scratch, oldTrap(Trap::IntegerDivideByZero));
|
||||
masm.branchTest64(Assembler::NonZero, r, r, scratch, &nonZero);
|
||||
trap(Trap::IntegerDivideByZero);
|
||||
masm.bind(&nonZero);
|
||||
}
|
||||
|
||||
void checkDivideSignedOverflowI32(RegI32 rhs, RegI32 srcDest, Label* done, bool zeroOnOverflow) {
|
||||
|
@ -1727,11 +1727,11 @@ wasm::GenerateStubs(const ModuleEnvironment& env, const FuncImportVector& import
|
||||
switch (trap) {
|
||||
case Trap::Unreachable:
|
||||
case Trap::IntegerOverflow:
|
||||
case Trap::IntegerDivideByZero:
|
||||
case Trap::StackOverflow:
|
||||
break;
|
||||
// The TODO list of "old" traps to convert to new traps:
|
||||
case Trap::InvalidConversionToInteger:
|
||||
case Trap::IntegerDivideByZero:
|
||||
case Trap::OutOfBounds:
|
||||
case Trap::UnalignedAccess:
|
||||
case Trap::IndirectCallToNull:
|
||||
|
Loading…
Reference in New Issue
Block a user