tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit e9fa485e4ac0f53d50f0a7ae49e10de7ca2deb84
parent 38a0c9534a4888903ecc02eb9f11aad7909438b9
Author: André Bargull <andre.bargull@gmail.com>
Date:   Thu,  6 Nov 2025 07:45:55 +0000

Bug 1998162: Improve lowering and codegen for div/mod instructions on riscv64. r=spidermonkey-reviewers,iain

Ports the changes from bug 1997975 to riscv64.

Changes:
- Splits the `DivOrMod` instructions into separate instructions.
- The `rem[w]` instruction returns zero for `INT_MIN % -1` on riscv64, so no
  extra code is needed to handle this case.
- `divw` returns `INT32_MIN` for `INT32_MIN / -1`, so we also don't need to
  special case this for truncated division.

Differential Revision: https://phabricator.services.mozilla.com/D271222

Diffstat:
Mjs/src/jit/LIROps.yaml | 47++++++++++++++++++++++++++++++++++++++++-------
Mjs/src/jit/riscv64/CodeGenerator-riscv64.cpp | 282++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
Mjs/src/jit/riscv64/LIR-riscv64.h | 103-------------------------------------------------------------------------------
Mjs/src/jit/riscv64/Lowering-riscv64.cpp | 46+++++++++++++++++++++-------------------------
4 files changed, 225 insertions(+), 253 deletions(-)

diff --git a/js/src/jit/LIROps.yaml b/js/src/jit/LIROps.yaml @@ -4119,7 +4119,7 @@ # Negative divisor case not implemented for all targets. negativeDivisor: bool #endif -#if defined(JS_CODEGEN_MIPS64) || defined(JS_CODEGEN_LOONG64) || defined(JS_CODEGEN_RISCV64) +#if defined(JS_CODEGEN_MIPS64) || defined(JS_CODEGEN_LOONG64) num_temps: 1 #endif mir_op: Div @@ -4639,14 +4639,47 @@ #endif #ifdef JS_CODEGEN_RISCV64 -- name: DivOrModI64 - gen_boilerplate: false +- name: UDiv + result_type: WordSized + operands: + lhs: WordSized + rhs: WordSized + mir_op: Div -- name: UDivOrMod - gen_boilerplate: false +- name: UMod + result_type: WordSized + operands: + lhs: WordSized + rhs: WordSized + mir_op: Mod -- name: UDivOrModI64 - gen_boilerplate: false +- name: DivI64 + result_type: Int64 + operands: + lhs: WordSized + rhs: WordSized + mir_op: Div + +- name: ModI64 + result_type: Int64 + operands: + lhs: WordSized + rhs: WordSized + mir_op: Mod + +- name: UDivI64 + result_type: Int64 + operands: + lhs: WordSized + rhs: WordSized + mir_op: Div + +- name: UModI64 + result_type: Int64 + operands: + lhs: WordSized + rhs: WordSized + mir_op: Mod - name: ModMaskI result_type: WordSized diff --git a/js/src/jit/riscv64/CodeGenerator-riscv64.cpp b/js/src/jit/riscv64/CodeGenerator-riscv64.cpp @@ -409,62 +409,82 @@ void CodeGeneratorRiscv64::emitBigIntPtrMod(LBigIntPtrMod* ins, masm.ma_mod64(output, dividend, divisor); } -void CodeGenerator::visitDivOrModI64(LDivOrModI64* lir) { +template <class LIR> +static void TrapIfDivideByZero(MacroAssembler& masm, LIR* lir, Register rhs) { + auto* mir = lir->mir(); + MOZ_ASSERT(mir->trapOnError()); + + if (mir->canBeDivideByZero()) { + Label nonZero; + masm.ma_b(rhs, rhs, &nonZero, Assembler::NonZero, ShortJump); + masm.wasmTrap(wasm::Trap::IntegerDivideByZero, mir->trapSiteDesc()); + masm.bind(&nonZero); + } +} + +void CodeGenerator::visitDivI64(LDivI64* lir) { Register lhs = ToRegister(lir->lhs()); Register rhs = ToRegister(lir->rhs()); Register output = ToRegister(lir->output()); - Label done; + MDiv* div = lir->mir(); // Handle divide by zero. - if (lir->canBeDivideByZero()) { - Label nonZero; - masm.ma_b(rhs, rhs, &nonZero, Assembler::NonZero); - masm.wasmTrap(wasm::Trap::IntegerDivideByZero, lir->trapSiteDesc()); - masm.bind(&nonZero); - } + TrapIfDivideByZero(masm, lir, rhs); // Handle an integer overflow exception from INT64_MIN / -1. - if (lir->canBeNegativeOverflow()) { + if (div->canBeNegativeOverflow()) { Label notOverflow; masm.branchPtr(Assembler::NotEqual, lhs, ImmWord(INT64_MIN), &notOverflow); masm.branchPtr(Assembler::NotEqual, rhs, ImmWord(-1), &notOverflow); - if (lir->mir()->isMod()) { - masm.ma_xor(output, output, Operand(output)); - } else { - masm.wasmTrap(wasm::Trap::IntegerOverflow, lir->trapSiteDesc()); - } - masm.jump(&done); + masm.wasmTrap(wasm::Trap::IntegerOverflow, div->trapSiteDesc()); masm.bind(&notOverflow); } - if (lir->mir()->isMod()) { - masm.ma_mod64(output, lhs, rhs); - } else { - masm.ma_div64(output, lhs, rhs); - } + masm.ma_div64(output, lhs, rhs); +} - masm.bind(&done); +void CodeGenerator::visitModI64(LModI64* lir) { + Register lhs = ToRegister(lir->lhs()); + Register rhs = ToRegister(lir->rhs()); + Register output = ToRegister(lir->output()); + + // rem result table: + // -------------------------------- + // | Dividend | Divisor | Result | + // |------------------------------| + // | X | 0 | X | + // | INT64_MIN | -1 | 0 | + // -------------------------------- + // + // NOTE: INT64_MIN % -1 returns 0, which is the expected result. + + // Handle divide by zero. + TrapIfDivideByZero(masm, lir, rhs); + + masm.ma_mod64(output, lhs, rhs); } -void CodeGenerator::visitUDivOrModI64(LUDivOrModI64* lir) { +void CodeGenerator::visitUDivI64(LUDivI64* lir) { Register lhs = ToRegister(lir->lhs()); Register rhs = ToRegister(lir->rhs()); Register output = ToRegister(lir->output()); // Prevent divide by zero. - if (lir->canBeDivideByZero()) { - Label nonZero; - masm.ma_b(rhs, rhs, &nonZero, Assembler::NonZero); - masm.wasmTrap(wasm::Trap::IntegerDivideByZero, lir->trapSiteDesc()); - masm.bind(&nonZero); - } + TrapIfDivideByZero(masm, lir, rhs); - if (lir->mir()->isMod()) { - masm.ma_modu64(output, lhs, rhs); - } else { - masm.ma_divu64(output, lhs, rhs); - } + masm.ma_divu64(output, lhs, rhs); +} + +void CodeGenerator::visitUModI64(LUModI64* lir) { + Register lhs = ToRegister(lir->lhs()); + Register rhs = ToRegister(lir->rhs()); + Register output = ToRegister(lir->output()); + + // Prevent divide by zero. + TrapIfDivideByZero(masm, lir, rhs); + + masm.ma_modu64(output, lhs, rhs); } void CodeGenerator::visitWasmLoadI64(LWasmLoadI64* lir) { @@ -996,18 +1016,26 @@ void CodeGenerator::visitDivI(LDivI* ins) { Register lhs = ToRegister(ins->lhs()); Register rhs = ToRegister(ins->rhs()); Register dest = ToRegister(ins->output()); - Register temp = ToRegister(ins->temp0()); MDiv* mir = ins->mir(); + // divw result table: + // ------------------------------------ + // | Dividend | Divisor | Result | + // |----------------------------------| + // | X | 0 | -1 | + // | INT32_MIN | -1 | INT32_MIN | + // ------------------------------------ + // + // NOTE: INT32_MIN / -1 returns INT32_MIN, which is the expected (truncated) + // result. Division by zero returns -1, whereas the truncated result should + // be 0, so it needs to be handled explicitly. + Label done; // Handle divide by zero. if (mir->canBeDivideByZero()) { if (mir->trapOnError()) { - Label nonZero; - masm.ma_b(rhs, rhs, &nonZero, Assembler::NonZero); - masm.wasmTrap(wasm::Trap::IntegerDivideByZero, mir->trapSiteDesc()); - masm.bind(&nonZero); + TrapIfDivideByZero(masm, ins, rhs); } else if (mir->canTruncateInfinities()) { // Truncated division by zero is zero (Infinity|0 == 0) Label notzero; @@ -1021,33 +1049,27 @@ void CodeGenerator::visitDivI(LDivI* ins) { } } - // Handle an integer overflow exception from -2147483648 / -1. - if (mir->canBeNegativeOverflow()) { + // Handle an integer overflow from (INT32_MIN / -1). + // The integer division gives INT32_MIN, but should be -(double)INT32_MIN. + if (mir->canBeNegativeOverflow() && + (mir->trapOnError() || !mir->canTruncateOverflow())) { Label notMinInt; - masm.move32(Imm32(INT32_MIN), temp); - masm.ma_b(lhs, temp, &notMinInt, Assembler::NotEqual, ShortJump); + masm.ma_b(lhs, Imm32(INT32_MIN), &notMinInt, Assembler::NotEqual, + ShortJump); - masm.move32(Imm32(-1), temp); if (mir->trapOnError()) { Label ok; - masm.ma_b(rhs, temp, &ok, Assembler::NotEqual); + masm.ma_b(rhs, Imm32(-1), &ok, Assembler::NotEqual, ShortJump); masm.wasmTrap(wasm::Trap::IntegerOverflow, mir->trapSiteDesc()); masm.bind(&ok); - } else if (mir->canTruncateOverflow()) { - // (-INT32_MIN)|0 == INT32_MIN - Label skip; - masm.ma_b(rhs, temp, &skip, Assembler::NotEqual, ShortJump); - masm.move32(Imm32(INT32_MIN), dest); - masm.ma_branch(&done, ShortJump); - masm.bind(&skip); } else { MOZ_ASSERT(mir->fallible()); - bailoutCmp32(Assembler::Equal, rhs, temp, ins->snapshot()); + bailoutCmp32(Assembler::Equal, rhs, Imm32(-1), ins->snapshot()); } masm.bind(&notMinInt); } - // Handle negative 0. (0/-Y) + // Handle negative zero: lhs == 0 && rhs < 0. if (!mir->canTruncateNegativeZero() && mir->canBeNegativeZero()) { Label nonzero; masm.ma_b(lhs, lhs, &nonzero, Assembler::NonZero, ShortJump); @@ -1062,6 +1084,9 @@ void CodeGenerator::visitDivI(LDivI* ins) { MOZ_ASSERT(mir->fallible()); MOZ_ASSERT(lhs != dest && rhs != dest); + UseScratchRegisterScope temps(masm); + Register temp = temps.Acquire(); + // The recommended code sequence to obtain both the quotient and remainder // is div[u] followed by mod[u]. masm.ma_div32(dest, lhs, rhs); @@ -1077,11 +1102,13 @@ void CodeGenerator::visitDivI(LDivI* ins) { void CodeGenerator::visitDivPowTwoI(LDivPowTwoI* ins) { Register lhs = ToRegister(ins->numerator()); Register dest = ToRegister(ins->output()); - Register tmp = ToRegister(ins->temp0()); int32_t shift = ins->shift(); MOZ_ASSERT(0 <= shift && shift <= 31); if (shift != 0) { + UseScratchRegisterScope temps(masm); + Register tmp = temps.Acquire(); + MDiv* mir = ins->mir(); if (!mir->isTruncated()) { // If the remainder is going to be != 0, bailout since this must @@ -1122,43 +1149,29 @@ void CodeGenerator::visitModI(LModI* ins) { MMod* mir = ins->mir(); Label done; - // Prevent INT_MIN % -1; - // The integer division will give INT_MIN, but we want -(double)INT_MIN. - if (mir->canBeNegativeDividend()) { - Label skip; - masm.ma_b(lhs, Imm32(INT_MIN), &skip, Assembler::NotEqual, ShortJump); - if (mir->isTruncated()) { - // (INT_MIN % -1)|0 == 0 - masm.ma_b(rhs, Imm32(-1), &skip, Assembler::NotEqual, ShortJump); - masm.move32(Imm32(0), dest); - masm.ma_branch(&done, ShortJump); - } else { - MOZ_ASSERT(mir->fallible()); - bailoutCmp32(Assembler::Equal, rhs, Imm32(-1), ins->snapshot()); - } - masm.bind(&skip); - } - - // X % Y (with X < 0, Y != 0) is bad because the result should - // have the sign of X, but -0 cannot be represented in - // integers. - // X % 0 is bad because it will give garbage, when it - // should give either \infty, -\infty or NAN. + // remw result table: + // -------------------------------- + // | Dividend | Divisor | Result | + // |------------------------------| + // | X | 0 | X | + // | INT32_MIN | -1 | 0 | + // -------------------------------- + // + // NOTE: INT32_MIN % -1 returns 0, which is the expected result. - // Testing X % Y. Compare Y with 0. - // If Y == 0, we bailout. + // Prevent divide by zero. if (mir->canBeDivideByZero()) { - if (mir->isTruncated()) { + if (mir->trapOnError()) { + TrapIfDivideByZero(masm, ins, rhs); + } else if (mir->isTruncated()) { + // Truncated division by zero yields integer zero. Label yNonZero; masm.ma_b(rhs, Imm32(0), &yNonZero, Assembler::NotEqual, ShortJump); - if (mir->trapOnError()) { - masm.wasmTrap(wasm::Trap::IntegerDivideByZero, mir->trapSiteDesc()); - } else { - masm.move32(Imm32(0), dest); - masm.ma_branch(&done, ShortJump); - } + masm.move32(Imm32(0), dest); + masm.ma_branch(&done, ShortJump); masm.bind(&yNonZero); } else { + // Non-truncated division by zero produces a non-integer. MOZ_ASSERT(mir->fallible()); bailoutCmp32(Assembler::Zero, rhs, rhs, ins->snapshot()); } @@ -1166,12 +1179,13 @@ void CodeGenerator::visitModI(LModI* ins) { masm.ma_mod32(dest, lhs, rhs); - // If X%Y == 0 and X < 0, then we *actually* wanted to return -0, so bailing - // out. -0.0|0 == 0 if (mir->canBeNegativeDividend() && !mir->isTruncated()) { MOZ_ASSERT(mir->fallible()); MOZ_ASSERT(lhs != dest); + // If dest == 0 and lhs < 0, then the result should be double -0.0. + // Note that this guard handles lhs == INT_MIN and rhs == -1. + masm.ma_b(dest, Imm32(0), &done, Assembler::NotEqual, ShortJump); bailoutCmp32(Assembler::Signed, lhs, lhs, ins->snapshot()); } @@ -2049,55 +2063,87 @@ void CodeGenerator::visitWasmCompareAndSelect(LWasmCompareAndSelect* ins) { trueExprAndDest); } -void CodeGenerator::visitUDivOrMod(LUDivOrMod* ins) { +void CodeGenerator::visitUDiv(LUDiv* ins) { Register lhs = ToRegister(ins->lhs()); Register rhs = ToRegister(ins->rhs()); Register output = ToRegister(ins->output()); Label done; + MDiv* mir = ins->mir(); + // Prevent divide by zero. - if (ins->canBeDivideByZero()) { - if (ins->mir()->isTruncated()) { - if (ins->trapOnError()) { - Label nonZero; - masm.ma_b(rhs, rhs, &nonZero, Assembler::NonZero); - masm.wasmTrap(wasm::Trap::IntegerDivideByZero, ins->trapSiteDesc()); - masm.bind(&nonZero); - } else { - // Infinity|0 == 0 - Label notzero; - masm.ma_b(rhs, rhs, &notzero, Assembler::NonZero, ShortJump); - masm.move32(Imm32(0), output); - masm.ma_branch(&done, ShortJump); - masm.bind(&notzero); - } + if (mir->canBeDivideByZero()) { + if (mir->trapOnError()) { + TrapIfDivideByZero(masm, ins, rhs); + } else if (mir->isTruncated()) { + // Infinity|0 == 0 + Label nonZero; + masm.ma_b(rhs, rhs, &nonZero, Assembler::NonZero, ShortJump); + masm.move32(Imm32(0), output); + masm.ma_branch(&done, ShortJump); + masm.bind(&nonZero); } else { bailoutCmp32(Assembler::Equal, rhs, Imm32(0), ins->snapshot()); } } // If the remainder is > 0, bailout since this must be a double. - if (ins->mir()->isDiv()) { - if (ins->mir()->toDiv()->canTruncateRemainder()) { - masm.ma_divu32(output, lhs, rhs); - } else { - MOZ_ASSERT(lhs != output && rhs != output); + if (mir->canTruncateRemainder()) { + masm.ma_divu32(output, lhs, rhs); + } else { + MOZ_ASSERT(lhs != output && rhs != output); - UseScratchRegisterScope temps(&masm); - Register scratch = temps.Acquire(); + UseScratchRegisterScope temps(&masm); + Register scratch = temps.Acquire(); - // The recommended code sequence to obtain both the quotient and remainder - // is div[u] followed by mod[u]. - masm.ma_divu32(output, lhs, rhs); - masm.ma_modu32(scratch, lhs, rhs); + // The recommended code sequence to obtain both the quotient and remainder + // is div[u] followed by mod[u]. + masm.ma_divu32(output, lhs, rhs); + masm.ma_modu32(scratch, lhs, rhs); - bailoutCmp32(Assembler::NonZero, scratch, scratch, ins->snapshot()); + bailoutCmp32(Assembler::NonZero, scratch, scratch, ins->snapshot()); + } + + // Unsigned div can return a value that's not a signed int32. + // If our users aren't expecting that, bail. + if (!mir->isTruncated()) { + bailoutCmp32(Assembler::LessThan, output, Imm32(0), ins->snapshot()); + } + + masm.bind(&done); +} + +void CodeGenerator::visitUMod(LUMod* ins) { + Register lhs = ToRegister(ins->lhs()); + Register rhs = ToRegister(ins->rhs()); + Register output = ToRegister(ins->output()); + Label done; + + MMod* mir = ins->mir(); + + // Prevent divide by zero. + if (mir->canBeDivideByZero()) { + if (mir->trapOnError()) { + TrapIfDivideByZero(masm, ins, rhs); + } else if (mir->isTruncated()) { + // NaN|0 == 0 + Label nonZero; + masm.ma_b(rhs, rhs, &nonZero, Assembler::NonZero, ShortJump); + masm.move32(Imm32(0), output); + masm.ma_branch(&done, ShortJump); + masm.bind(&nonZero); + } else { + bailoutCmp32(Assembler::Equal, rhs, Imm32(0), ins->snapshot()); } - } else { - masm.ma_modu32(output, lhs, rhs); } - if (!ins->mir()->isTruncated()) { + masm.ma_modu32(output, lhs, rhs); + + // Bail if the output would be negative. + // + // LUMod inputs may be Uint32, so care is taken to ensure the result is not + // unexpectedly signed. + if (!mir->isTruncated()) { bailoutCmp32(Assembler::LessThan, output, Imm32(0), ins->snapshot()); } diff --git a/js/src/jit/riscv64/LIR-riscv64.h b/js/src/jit/riscv64/LIR-riscv64.h @@ -26,109 +26,6 @@ class LUnbox : public LInstructionHelper<1, BOX_PIECES, 0> { const char* extraName() const { return StringFromMIRType(mir()->type()); } }; -class LUDivOrMod : public LBinaryMath<0> { - public: - LIR_HEADER(UDivOrMod); - - LUDivOrMod() : LBinaryMath(classOpcode) {} - - MBinaryArithInstruction* mir() const { - MOZ_ASSERT(mir_->isDiv() || mir_->isMod()); - return static_cast<MBinaryArithInstruction*>(mir_); - } - - bool canBeDivideByZero() const { - if (mir_->isMod()) { - return mir_->toMod()->canBeDivideByZero(); - } - return mir_->toDiv()->canBeDivideByZero(); - } - - bool trapOnError() const { - if (mir_->isMod()) { - return mir_->toMod()->trapOnError(); - } - return mir_->toDiv()->trapOnError(); - } - - const wasm::TrapSiteDesc& trapSiteDesc() const { - MOZ_ASSERT(mir_->isDiv() || mir_->isMod()); - if (mir_->isMod()) { - return mir_->toMod()->trapSiteDesc(); - } - return mir_->toDiv()->trapSiteDesc(); - } -}; - -class LDivOrModI64 : public LBinaryMath<0> { - public: - LIR_HEADER(DivOrModI64); - - LDivOrModI64(const LAllocation& lhs, const LAllocation& rhs) - : LBinaryMath(classOpcode) { - setOperand(0, lhs); - setOperand(1, rhs); - } - - MBinaryArithInstruction* mir() const { - MOZ_ASSERT(mir_->isDiv() || mir_->isMod()); - return static_cast<MBinaryArithInstruction*>(mir_); - } - - bool canBeDivideByZero() const { - if (mir_->isMod()) { - return mir_->toMod()->canBeDivideByZero(); - } - return mir_->toDiv()->canBeDivideByZero(); - } - bool canBeNegativeOverflow() const { - if (mir_->isMod()) { - return mir_->toMod()->canBeNegativeDividend(); - } - return mir_->toDiv()->canBeNegativeOverflow(); - } - const wasm::TrapSiteDesc& trapSiteDesc() const { - MOZ_ASSERT(mir_->isDiv() || mir_->isMod()); - if (mir_->isMod()) { - return mir_->toMod()->trapSiteDesc(); - } - return mir_->toDiv()->trapSiteDesc(); - } -}; - -class LUDivOrModI64 : public LBinaryMath<0> { - public: - LIR_HEADER(UDivOrModI64); - - LUDivOrModI64(const LAllocation& lhs, const LAllocation& rhs) - : LBinaryMath(classOpcode) { - setOperand(0, lhs); - setOperand(1, rhs); - } - - const char* extraName() const { - return mir()->isTruncated() ? "Truncated" : nullptr; - } - - MBinaryArithInstruction* mir() const { - MOZ_ASSERT(mir_->isDiv() || mir_->isMod()); - return static_cast<MBinaryArithInstruction*>(mir_); - } - bool canBeDivideByZero() const { - if (mir_->isMod()) { - return mir_->toMod()->canBeDivideByZero(); - } - return mir_->toDiv()->canBeDivideByZero(); - } - const wasm::TrapSiteDesc& trapSiteDesc() const { - MOZ_ASSERT(mir_->isDiv() || mir_->isMod()); - if (mir_->isMod()) { - return mir_->toMod()->trapSiteDesc(); - } - return mir_->toDiv()->trapSiteDesc(); - } -}; - } // namespace jit } // namespace js diff --git a/js/src/jit/riscv64/Lowering-riscv64.cpp b/js/src/jit/riscv64/Lowering-riscv64.cpp @@ -18,8 +18,6 @@ using namespace js; using namespace js::jit; -using mozilla::FloorLog2; - LTableSwitch* LIRGeneratorRiscv64::newLTableSwitch( const LAllocation& in, const LDefinition& inputCopy) { return new (alloc()) LTableSwitch(in, inputCopy, temp()); @@ -179,10 +177,10 @@ void LIRGeneratorRiscv64::lowerDivI(MDiv* div) { // possible; division by negative powers of two can be optimized in a // similar manner as positive powers of two, and division by other // constants can be optimized by a reciprocal multiplication technique. - int32_t shift = FloorLog2(rhs); - if (rhs > 0 && 1 << shift == rhs) { - auto* lir = new (alloc()) - LDivPowTwoI(useRegisterAtStart(div->lhs()), temp(), shift); + if (rhs > 0 && mozilla::IsPowerOfTwo(mozilla::Abs(rhs))) { + int32_t shift = mozilla::FloorLog2(rhs); + auto* lir = + new (alloc()) LDivPowTwoI(useRegisterAtStart(div->lhs()), shift); if (div->fallible()) { assignSnapshot(lir, div->bailoutKind()); } @@ -200,7 +198,9 @@ void LIRGeneratorRiscv64::lowerDivI(MDiv* div) { rhs = useRegisterAtStart(div->rhs()); } - auto* lir = new (alloc()) LDivI(lhs, rhs, temp()); + // RISCV64 has plenty of scratch registers, so we don't need to request an + // additonal temp register from the register allocator. + auto* lir = new (alloc()) LDivI(lhs, rhs, LDefinition::BogusTemp()); if (div->fallible()) { assignSnapshot(lir, div->bailoutKind()); } @@ -208,15 +208,15 @@ void LIRGeneratorRiscv64::lowerDivI(MDiv* div) { } void LIRGeneratorRiscv64::lowerDivI64(MDiv* div) { - auto* lir = new (alloc()) LDivOrModI64(useRegisterAtStart(div->lhs()), - useRegisterAtStart(div->rhs())); + auto* lir = new (alloc()) + LDivI64(useRegisterAtStart(div->lhs()), useRegisterAtStart(div->rhs())); defineInt64(lir, div); } void LIRGeneratorRiscv64::lowerModI(MMod* mod) { if (mod->rhs()->isConstant()) { int32_t rhs = mod->rhs()->toConstant()->toInt32(); - int32_t shift = FloorLog2(rhs); + int32_t shift = mozilla::FloorLog2(rhs); if (rhs > 0 && 1 << shift == rhs) { LModPowTwoI* lir = new (alloc()) LModPowTwoI(useRegisterAtStart(mod->lhs()), shift); @@ -225,7 +225,8 @@ void LIRGeneratorRiscv64::lowerModI(MMod* mod) { } define(lir, mod); return; - } else if (shift < 31 && (1 << (shift + 1)) - 1 == rhs) { + } + if (shift < 31 && (1 << (shift + 1)) - 1 == rhs) { LModMaskI* lir = new (alloc()) LModMaskI(useRegister(mod->lhs()), temp(), temp(), shift + 1); if (mod->fallible()) { @@ -253,8 +254,8 @@ void LIRGeneratorRiscv64::lowerModI(MMod* mod) { } void LIRGeneratorRiscv64::lowerModI64(MMod* mod) { - auto* lir = new (alloc()) LDivOrModI64(useRegisterAtStart(mod->lhs()), - useRegisterAtStart(mod->rhs())); + auto* lir = new (alloc()) + LModI64(useRegisterAtStart(mod->lhs()), useRegisterAtStart(mod->rhs())); defineInt64(lir, mod); } @@ -268,36 +269,31 @@ void LIRGeneratorRiscv64::lowerUDiv(MDiv* div) { rhs = useRegisterAtStart(div->rhs()); } - auto* lir = new (alloc()) LUDivOrMod; - lir->setOperand(0, lhs); - lir->setOperand(1, rhs); + auto* lir = new (alloc()) LUDiv(lhs, rhs); if (div->fallible()) { assignSnapshot(lir, div->bailoutKind()); } - define(lir, div); } void LIRGeneratorRiscv64::lowerUDivI64(MDiv* div) { - auto* lir = new (alloc()) LUDivOrModI64(useRegisterAtStart(div->lhs()), - useRegisterAtStart(div->rhs())); + auto* lir = new (alloc()) + LUDivI64(useRegisterAtStart(div->lhs()), useRegisterAtStart(div->rhs())); defineInt64(lir, div); } void LIRGeneratorRiscv64::lowerUMod(MMod* mod) { - auto* lir = new (alloc()) LUDivOrMod; - lir->setOperand(0, useRegisterAtStart(mod->lhs())); - lir->setOperand(1, useRegisterAtStart(mod->rhs())); + auto* lir = new (alloc()) + LUMod(useRegisterAtStart(mod->lhs()), useRegisterAtStart(mod->rhs())); if (mod->fallible()) { assignSnapshot(lir, mod->bailoutKind()); } - define(lir, mod); } void LIRGeneratorRiscv64::lowerUModI64(MMod* mod) { - auto* lir = new (alloc()) LUDivOrModI64(useRegisterAtStart(mod->lhs()), - useRegisterAtStart(mod->rhs())); + auto* lir = new (alloc()) + LUModI64(useRegisterAtStart(mod->lhs()), useRegisterAtStart(mod->rhs())); defineInt64(lir, mod); }