void CodeGeneratorX86::visitDivOrModI64(LDivOrModI64* lir) { Register64 lhs = ToRegister64(lir->getInt64Operand(LDivOrModI64::Lhs)); Register64 rhs = ToRegister64(lir->getInt64Operand(LDivOrModI64::Rhs)); Register temp = ToRegister(lir->temp()); Register64 output = ToOutRegister64(lir); MOZ_ASSERT(output == ReturnReg64); Label done; // Handle divide by zero. if (lir->canBeDivideByZero()) masm.branchTest64(Assembler::Zero, rhs, rhs, temp, trap(lir, wasm::Trap::IntegerDivideByZero)); MDefinition* mir = lir->mir(); // Handle an integer overflow exception from INT64_MIN / -1. if (lir->canBeNegativeOverflow()) { Label notmin; masm.branch64(Assembler::NotEqual, lhs, Imm64(INT64_MIN), ¬min); masm.branch64(Assembler::NotEqual, rhs, Imm64(-1), ¬min); if (mir->isMod()) masm.xor64(output, output); else masm.jump(trap(lir, wasm::Trap::IntegerOverflow)); masm.jump(&done); masm.bind(¬min); } masm.setupWasmABICall(); masm.passABIArg(lhs.high); masm.passABIArg(lhs.low); masm.passABIArg(rhs.high); masm.passABIArg(rhs.low); MOZ_ASSERT(gen->compilingWasm()); if (mir->isMod()) masm.callWithABI(lir->bytecodeOffset(), wasm::SymbolicAddress::ModI64); else masm.callWithABI(lir->bytecodeOffset(), wasm::SymbolicAddress::DivI64); // output in edx:eax, move to output register. masm.movl(edx, output.high); MOZ_ASSERT(eax == output.low); masm.bind(&done); }
void CodeGeneratorX86::visitUDivOrModI64(LUDivOrModI64* lir) { Register64 lhs = ToRegister64(lir->getInt64Operand(LDivOrModI64::Lhs)); Register64 rhs = ToRegister64(lir->getInt64Operand(LDivOrModI64::Rhs)); Register temp = ToRegister(lir->temp()); Register64 output = ToOutRegister64(lir); MOZ_ASSERT(output == ReturnReg64); // Prevent divide by zero. if (lir->canBeDivideByZero()) masm.branchTest64(Assembler::Zero, rhs, rhs, temp, trap(lir, wasm::Trap::IntegerDivideByZero)); masm.setupWasmABICall(); masm.passABIArg(lhs.high); masm.passABIArg(lhs.low); masm.passABIArg(rhs.high); masm.passABIArg(rhs.low); MOZ_ASSERT(gen->compilingWasm()); MDefinition* mir = lir->mir(); if (mir->isMod()) masm.callWithABI(lir->bytecodeOffset(), wasm::SymbolicAddress::UModI64); else masm.callWithABI(lir->bytecodeOffset(), wasm::SymbolicAddress::UDivI64); // output in edx:eax, move to output register. masm.movl(edx, output.high); MOZ_ASSERT(eax == output.low); }