tor-browser

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

commit 56c5cc20609ed6ff5c4c3af310755770b42ee6fc
parent da494342cf7c537190eeea74b7a82ec37de89468
Author: André Bargull <andre.bargull@gmail.com>
Date:   Mon, 20 Oct 2025 08:20:22 +0000

Bug 1993951 - Part 1: Implement MacroAssembler::copySign{Float32,Double} for ARM. r=spidermonkey-reviewers,iain

GCC emits this instruction sequence for `std::copysign`. It needs fewer instructions
and registers, which helps to move `LCopySign` into the shared code generator.

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

Diffstat:
Mjs/src/jit/MacroAssembler.h | 2+-
Mjs/src/jit/arm/CodeGenerator-arm.cpp | 44++------------------------------------------
Mjs/src/jit/arm/Lowering-arm.cpp | 3---
Mjs/src/jit/arm/MacroAssembler-arm.cpp | 28+++++++++++++++++++++++++++-
4 files changed, 30 insertions(+), 47 deletions(-)

diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h @@ -1328,7 +1328,7 @@ class MacroAssembler : public MacroAssemblerSpecific { void copySignDouble(FloatRegister lhs, FloatRegister rhs, FloatRegister output) PER_SHARED_ARCH; void copySignFloat32(FloatRegister lhs, FloatRegister rhs, - FloatRegister output) DEFINED_ON(x86_shared, arm64); + FloatRegister output) DEFINED_ON(arm, arm64, x86_shared); // Returns a random double in range [0, 1) in |dest|. The |rng| register must // hold a pointer to a mozilla::non_crypto::XorShift128PlusRNG. diff --git a/js/src/jit/arm/CodeGenerator-arm.cpp b/js/src/jit/arm/CodeGenerator-arm.cpp @@ -2366,24 +2366,7 @@ void CodeGenerator::visitCopySignF(LCopySignF* ins) { FloatRegister rhs = ToFloatRegister(ins->rhs()); FloatRegister output = ToFloatRegister(ins->output()); - Register lhsi = ToRegister(ins->temp0()); - Register rhsi = ToRegister(ins->temp1()); - - masm.ma_vxfer(lhs, lhsi); - masm.ma_vxfer(rhs, rhsi); - - ScratchRegisterScope scratch(masm); - - // Clear lhs's sign. - masm.ma_and(Imm32(INT32_MAX), lhsi, lhsi, scratch); - - // Keep rhs's sign. - masm.ma_and(Imm32(INT32_MIN), rhsi, rhsi, scratch); - - // Combine. - masm.ma_orr(lhsi, rhsi, rhsi); - - masm.ma_vxfer(rhsi, output); + masm.copySignFloat32(lhs, rhs, output); } void CodeGenerator::visitCopySignD(LCopySignD* ins) { @@ -2391,30 +2374,7 @@ void CodeGenerator::visitCopySignD(LCopySignD* ins) { FloatRegister rhs = ToFloatRegister(ins->rhs()); FloatRegister output = ToFloatRegister(ins->output()); - Register lhsi = ToRegister(ins->temp0()); - Register rhsi = ToRegister(ins->temp1()); - - // Manipulate high words of double inputs. - masm.as_vxfer(lhsi, InvalidReg, lhs, Assembler::FloatToCore, - Assembler::Always, 1); - masm.as_vxfer(rhsi, InvalidReg, rhs, Assembler::FloatToCore, - Assembler::Always, 1); - - ScratchRegisterScope scratch(masm); - - // Clear lhs's sign. - masm.ma_and(Imm32(INT32_MAX), lhsi, lhsi, scratch); - - // Keep rhs's sign. - masm.ma_and(Imm32(INT32_MIN), rhsi, rhsi, scratch); - - // Combine. - masm.ma_orr(lhsi, rhsi, rhsi); - - // Reconstruct the output. - masm.as_vxfer(lhsi, InvalidReg, lhs, Assembler::FloatToCore, - Assembler::Always, 0); - masm.ma_vxfer(lhsi, rhsi, output); + masm.copySignDouble(lhs, rhs, output); } void CodeGenerator::visitWrapInt64ToInt32(LWrapInt64ToInt32* lir) { diff --git a/js/src/jit/arm/Lowering-arm.cpp b/js/src/jit/arm/Lowering-arm.cpp @@ -1145,9 +1145,6 @@ void LIRGenerator::visitCopySign(MCopySign* ins) { lir = new (alloc()) LCopySignF(); } - lir->setTemp(0, temp()); - lir->setTemp(1, temp()); - lowerForFPU(lir, ins, lhs, rhs); } diff --git a/js/src/jit/arm/MacroAssembler-arm.cpp b/js/src/jit/arm/MacroAssembler-arm.cpp @@ -6188,7 +6188,33 @@ void MacroAssembler::nearbyIntFloat32(RoundingMode mode, FloatRegister src, void MacroAssembler::copySignDouble(FloatRegister lhs, FloatRegister rhs, FloatRegister output) { - MOZ_CRASH("not supported on this platform"); + ScratchRegisterScope scratch(*this); + + // Transfer top word of |rhs| into GPR. + as_vxfer(scratch, InvalidReg, rhs, Assembler::FloatToCore, Assembler::Always, + 1); + + // Move |lhs| with sign-bit cleared into |output|. + ma_vabs(lhs, output); + + // Negate |output| if sign bit of |rhs| is set. + as_cmp(scratch, Imm8(0)); + ma_vneg(output, output, Assembler::LessThan); +} + +void MacroAssembler::copySignFloat32(FloatRegister lhs, FloatRegister rhs, + FloatRegister output) { + ScratchRegisterScope scratch(*this); + + // Transfer |rhs| into GPR. + ma_vxfer(rhs, scratch); + + // Move |lhs| with sign-bit cleared into |output|. + ma_vabs_f32(lhs, output); + + // Negate |output| if sign bit of |rhs| is set. + as_cmp(scratch, Imm8(0)); + ma_vneg_f32(output, output, Assembler::LessThan); } void MacroAssembler::shiftIndex32AndAdd(Register indexTemp32, int shift,