tor-browser

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

commit 46af4d9a893a594fd1dbc8ee5d2dbe4ba8a69baf
parent f8e4fb61645e565b3d8d876c7f351a509bcd354c
Author: André Bargull <andre.bargull@gmail.com>
Date:   Thu, 23 Oct 2025 09:56:07 +0000

Bug 1995490 - Part 2: Replace modulus with bit-and for shift/rotate with immediate. r=spidermonkey-reviewers,iain

Shift and rotate instructions are defined as using the low five resp. six bits.
This is more accurately implemented when using bit-and instead of (signed)
integer modulus.

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

Diffstat:
Mjs/src/jit/loong64/CodeGenerator-loong64.cpp | 19++++++++++---------
Mjs/src/jit/loong64/MacroAssembler-loong64-inl.h | 6+++---
Mjs/src/jit/loong64/Simulator-loong64.cpp | 16++++++++--------
Mjs/src/jit/mips-shared/MacroAssembler-mips-shared.cpp | 18+++++++++---------
Mjs/src/jit/riscv64/CodeGenerator-riscv64.cpp | 13+++++++------
Mjs/src/jit/riscv64/MacroAssembler-riscv64-inl.h | 6+++---
Mjs/src/jit/riscv64/MacroAssembler-riscv64.cpp | 12++++--------
7 files changed, 44 insertions(+), 46 deletions(-)

diff --git a/js/src/jit/loong64/CodeGenerator-loong64.cpp b/js/src/jit/loong64/CodeGenerator-loong64.cpp @@ -1079,19 +1079,20 @@ void CodeGenerator::visitDivPowTwoI(LDivPowTwoI* ins) { Register dest = ToRegister(ins->output()); Register tmp = ToRegister(ins->temp0()); int32_t shift = ins->shift(); + MOZ_ASSERT(0 <= shift && shift <= 31); if (shift != 0) { MDiv* mir = ins->mir(); if (!mir->isTruncated()) { // If the remainder is going to be != 0, bailout since this must // be a double. - masm.as_slli_w(tmp, lhs, (32 - shift) % 32); + masm.as_slli_w(tmp, lhs, (32 - shift)); bailoutCmp32(Assembler::NonZero, tmp, tmp, ins->snapshot()); } if (!mir->canBeNegativeDividend()) { // Numerator is unsigned, so needs no adjusting. Do the shift. - masm.as_srai_w(dest, lhs, shift % 32); + masm.as_srai_w(dest, lhs, shift); return; } @@ -1100,15 +1101,15 @@ void CodeGenerator::visitDivPowTwoI(LDivPowTwoI* ins) { // Power of 2" in Henry S. Warren, Jr.'s Hacker's Delight. if (shift > 1) { masm.as_srai_w(tmp, lhs, 31); - masm.as_srli_w(tmp, tmp, (32 - shift) % 32); + masm.as_srli_w(tmp, tmp, (32 - shift)); masm.add32(lhs, tmp); } else { - masm.as_srli_w(tmp, lhs, (32 - shift) % 32); + masm.as_srli_w(tmp, lhs, (32 - shift)); masm.add32(lhs, tmp); } // Do the shift. - masm.as_srai_w(dest, tmp, shift % 32); + masm.as_srai_w(dest, tmp, shift); } else { masm.move32(lhs, dest); } @@ -1302,21 +1303,21 @@ void CodeGenerator::visitShiftI(LShiftI* ins) { switch (ins->bitop()) { case JSOp::Lsh: if (shift) { - masm.as_slli_w(dest, lhs, shift % 32); + masm.as_slli_w(dest, lhs, shift); } else { masm.move32(lhs, dest); } break; case JSOp::Rsh: if (shift) { - masm.as_srai_w(dest, lhs, shift % 32); + masm.as_srai_w(dest, lhs, shift); } else { masm.move32(lhs, dest); } break; case JSOp::Ursh: if (shift) { - masm.as_srli_w(dest, lhs, shift % 32); + masm.as_srli_w(dest, lhs, shift); } else { // x >>> 0 can overflow. if (ins->mir()->toUrsh()->fallible()) { @@ -1441,7 +1442,7 @@ void CodeGenerator::visitUrshD(LUrshD* ins) { FloatRegister out = ToFloatRegister(ins->output()); if (rhs->isConstant()) { - masm.as_srli_w(temp, lhs, ToInt32(rhs) % 32); + masm.as_srli_w(temp, lhs, ToInt32(rhs) & 0x1f); } else { masm.as_srl_w(temp, lhs, ToRegister(rhs)); } diff --git a/js/src/jit/loong64/MacroAssembler-loong64-inl.h b/js/src/jit/loong64/MacroAssembler-loong64-inl.h @@ -735,7 +735,7 @@ void MacroAssembler::lshift32(Imm32 imm, Register dest) { } void MacroAssembler::lshift32(Imm32 imm, Register src, Register dest) { - as_slli_w(dest, src, imm.value % 32); + as_slli_w(dest, src, imm.value & 0x1f); } void MacroAssembler::flexibleLshift32(Register src, Register dest) { @@ -777,7 +777,7 @@ void MacroAssembler::rshift32(Imm32 imm, Register dest) { } void MacroAssembler::rshift32(Imm32 imm, Register src, Register dest) { - as_srli_w(dest, src, imm.value % 32); + as_srli_w(dest, src, imm.value & 0x1f); } void MacroAssembler::flexibleRshift32(Register src, Register dest) { @@ -794,7 +794,7 @@ void MacroAssembler::rshift32Arithmetic(Imm32 imm, Register dest) { void MacroAssembler::rshift32Arithmetic(Imm32 imm, Register src, Register dest) { - as_srai_w(dest, src, imm.value % 32); + as_srai_w(dest, src, imm.value & 0x1f); } void MacroAssembler::flexibleRshift32Arithmetic(Register src, Register dest) { diff --git a/js/src/jit/loong64/Simulator-loong64.cpp b/js/src/jit/loong64/Simulator-loong64.cpp @@ -3424,38 +3424,38 @@ void Simulator::decodeTypeOp17(SimInstruction* instr) { setRegister(rd_reg(instr), rj(instr) & (~rk(instr))); break; case op_sll_w: - setRegister(rd_reg(instr), (int32_t)rj(instr) << (rk_u(instr) % 32)); + setRegister(rd_reg(instr), (int32_t)rj(instr) << (rk_u(instr) & 0x1f)); break; case op_srl_w: { alu_out = - static_cast<int32_t>((uint32_t)rj_u(instr) >> (rk_u(instr) % 32)); + static_cast<int32_t>((uint32_t)rj_u(instr) >> (rk_u(instr) & 0x1f)); setRegister(rd_reg(instr), alu_out); break; } case op_sra_w: - setRegister(rd_reg(instr), (int32_t)rj(instr) >> (rk_u(instr) % 32)); + setRegister(rd_reg(instr), (int32_t)rj(instr) >> (rk_u(instr) & 0x1f)); break; case op_sll_d: - setRegister(rd_reg(instr), rj(instr) << (rk_u(instr) % 64)); + setRegister(rd_reg(instr), rj(instr) << (rk_u(instr) & 0x3f)); break; case op_srl_d: { - alu_out = static_cast<int64_t>(rj_u(instr) >> (rk_u(instr) % 64)); + alu_out = static_cast<int64_t>(rj_u(instr) >> (rk_u(instr) & 0x3f)); setRegister(rd_reg(instr), alu_out); break; } case op_sra_d: - setRegister(rd_reg(instr), rj(instr) >> (rk_u(instr) % 64)); + setRegister(rd_reg(instr), rj(instr) >> (rk_u(instr) & 0x3f)); break; case op_rotr_w: { alu_out = static_cast<int32_t>( RotateRight32(static_cast<const uint32_t>(rj_u(instr)), - static_cast<const uint32_t>(rk_u(instr) % 32))); + static_cast<const uint32_t>(rk_u(instr) & 0x1f))); setRegister(rd_reg(instr), alu_out); break; } case op_rotr_d: { alu_out = static_cast<int64_t>( - RotateRight64((rj_u(instr)), (rk_u(instr) % 64))); + RotateRight64((rj_u(instr)), (rk_u(instr) & 0x3f))); setRegister(rd_reg(instr), alu_out); break; } diff --git a/js/src/jit/mips-shared/MacroAssembler-mips-shared.cpp b/js/src/jit/mips-shared/MacroAssembler-mips-shared.cpp @@ -48,36 +48,36 @@ void MacroAssemblerMIPSShared::ma_liPatchable(Register dest, Imm32 imm) { // Shifts void MacroAssemblerMIPSShared::ma_sll(Register rd, Register rt, Imm32 shift) { - as_sll(rd, rt, shift.value % 32); + as_sll(rd, rt, shift.value & 0x1f); } void MacroAssemblerMIPSShared::ma_srl(Register rd, Register rt, Imm32 shift) { - as_srl(rd, rt, shift.value % 32); + as_srl(rd, rt, shift.value & 0x1f); } void MacroAssemblerMIPSShared::ma_sra(Register rd, Register rt, Imm32 shift) { - as_sra(rd, rt, shift.value % 32); + as_sra(rd, rt, shift.value & 0x1f); } void MacroAssemblerMIPSShared::ma_ror(Register rd, Register rt, Imm32 shift) { if (hasR2()) { - as_rotr(rd, rt, shift.value % 32); + as_rotr(rd, rt, shift.value & 0x1f); } else { UseScratchRegisterScope temps(*this); Register scratch = temps.Acquire(); - as_srl(scratch, rt, shift.value % 32); - as_sll(rd, rt, (32 - (shift.value % 32)) % 32); + as_srl(scratch, rt, shift.value & 0x1f); + as_sll(rd, rt, 32 - (shift.value & 0x1f)); as_or(rd, rd, scratch); } } void MacroAssemblerMIPSShared::ma_rol(Register rd, Register rt, Imm32 shift) { if (hasR2()) { - as_rotr(rd, rt, (32 - (shift.value % 32)) % 32); + as_rotr(rd, rt, 32 - (shift.value & 0x1f)); } else { UseScratchRegisterScope temps(*this); Register scratch = temps.Acquire(); - as_srl(scratch, rt, (32 - (shift.value % 32)) % 32); - as_sll(rd, rt, shift.value % 32); + as_srl(scratch, rt, 32 - (shift.value & 0x1f)); + as_sll(rd, rt, shift.value & 0x1f); as_or(rd, rd, scratch); } } diff --git a/js/src/jit/riscv64/CodeGenerator-riscv64.cpp b/js/src/jit/riscv64/CodeGenerator-riscv64.cpp @@ -1139,19 +1139,20 @@ void CodeGenerator::visitDivPowTwoI(LDivPowTwoI* ins) { Register dest = ToRegister(ins->output()); Register tmp = ToRegister(ins->temp0()); int32_t shift = ins->shift(); + MOZ_ASSERT(0 <= shift && shift <= 31); if (shift != 0) { MDiv* mir = ins->mir(); if (!mir->isTruncated()) { // If the remainder is going to be != 0, bailout since this must // be a double. - masm.slliw(tmp, lhs, (32 - shift) % 32); + masm.slliw(tmp, lhs, (32 - shift)); bailoutCmp32(Assembler::NonZero, tmp, tmp, ins->snapshot()); } if (!mir->canBeNegativeDividend()) { // Numerator is unsigned, so needs no adjusting. Do the shift. - masm.sraiw(dest, lhs, shift % 32); + masm.sraiw(dest, lhs, shift); return; } @@ -1160,15 +1161,15 @@ void CodeGenerator::visitDivPowTwoI(LDivPowTwoI* ins) { // Power of 2" in Henry S. Warren, Jr.'s Hacker's Delight. if (shift > 1) { masm.sraiw(tmp, lhs, 31); - masm.srliw(tmp, tmp, (32 - shift) % 32); + masm.srliw(tmp, tmp, (32 - shift)); masm.add32(lhs, tmp); } else { - masm.srliw(tmp, lhs, (32 - shift) % 32); + masm.srliw(tmp, lhs, (32 - shift)); masm.add32(lhs, tmp); } // Do the shift. - masm.sraiw(dest, tmp, shift % 32); + masm.sraiw(dest, tmp, shift); } else { masm.move32(lhs, dest); } @@ -1527,7 +1528,7 @@ void CodeGenerator::visitUrshD(LUrshD* ins) { FloatRegister out = ToFloatRegister(ins->output()); if (rhs->isConstant()) { - masm.srliw(temp, lhs, ToInt32(rhs) % 32); + masm.srliw(temp, lhs, ToInt32(rhs) & 0x1f); } else { masm.srlw(temp, lhs, ToRegister(rhs)); } diff --git a/js/src/jit/riscv64/MacroAssembler-riscv64-inl.h b/js/src/jit/riscv64/MacroAssembler-riscv64-inl.h @@ -1592,7 +1592,7 @@ void MacroAssembler::lshift32(Imm32 imm, Register dest) { } void MacroAssembler::lshift32(Imm32 imm, Register src, Register dest) { - slliw(dest, src, imm.value % 32); + slliw(dest, src, imm.value & 0x1f); } void MacroAssembler::lshift64(Register shift, Register64 dest) { @@ -2006,7 +2006,7 @@ void MacroAssembler::rshift32Arithmetic(Imm32 imm, Register dest) { void MacroAssembler::rshift32Arithmetic(Imm32 imm, Register src, Register dest) { - sraiw(dest, src, imm.value % 32); + sraiw(dest, src, imm.value & 0x1f); } void MacroAssembler::rshift32(Register src, Register dest) { @@ -2018,7 +2018,7 @@ void MacroAssembler::rshift32(Imm32 imm, Register dest) { } void MacroAssembler::rshift32(Imm32 imm, Register src, Register dest) { - srliw(dest, src, imm.value % 32); + srliw(dest, src, imm.value & 0x1f); } void MacroAssembler::rshift64Arithmetic(Imm32 imm, Register64 dest) { diff --git a/js/src/jit/riscv64/MacroAssembler-riscv64.cpp b/js/src/jit/riscv64/MacroAssembler-riscv64.cpp @@ -6742,7 +6742,7 @@ void MacroAssemblerRiscv64::Rol(Register rd, Register rs, const Operand& rt) { or_(rd, scratch, rd); sext_w(rd, rd); } else { - Ror(rd, rs, Operand(32 - (rt.immediate() % 32))); + Ror(rd, rs, Operand(32 - (rt.immediate() & 0x1f))); } } @@ -6756,12 +6756,10 @@ void MacroAssemblerRiscv64::Ror(Register rd, Register rs, const Operand& rt) { or_(rd, scratch, rd); sext_w(rd, rd); } else { - int64_t ror_value = rt.immediate() % 32; + int64_t ror_value = rt.immediate() & 0x1f; if (ror_value == 0) { mv(rd, rs); return; - } else if (ror_value < 0) { - ror_value += 32; } srliw(scratch, rs, ror_value); slliw(rd, rs, 32 - ror_value); @@ -6780,7 +6778,7 @@ void MacroAssemblerRiscv64::Drol(Register rd, Register rs, const Operand& rt) { sll(rd, rs, rt.rm()); or_(rd, scratch, rd); } else { - Dror(rd, rs, Operand(64 - (rt.immediate() % 64))); + Dror(rd, rs, Operand(64 - (rt.immediate() & 0x3f))); } } @@ -6793,12 +6791,10 @@ void MacroAssemblerRiscv64::Dror(Register rd, Register rs, const Operand& rt) { srl(rd, rs, rt.rm()); or_(rd, scratch, rd); } else { - int64_t dror_value = rt.immediate() % 64; + int64_t dror_value = rt.immediate() & 0x3f; if (dror_value == 0) { mv(rd, rs); return; - } else if (dror_value < 0) { - dror_value += 64; } srli(scratch, rs, dror_value); slli(rd, rs, 64 - dror_value);