tor-browser

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

commit c86d5fd6f9060cce9fecd654fcd951d8188c36e4
parent 677f59ac097c07fd9466cd8b4df0dcef45faaf39
Author: André Bargull <andre.bargull@gmail.com>
Date:   Fri, 17 Oct 2025 11:25:44 +0000

Bug 1994189: Emit fewer instructions for floating point comparison. r=spidermonkey-reviewers,iain

`x !== x` produced this assembly:
```asm
[Codegen]                                 # LIR=CompareD
[Codegen] a20022d3       feq.d     t0, ft0, ft0
[Codegen] a2002ed3       feq.d     t4, ft0, ft0
[Codegen] 01d2f2b3       and       t0, t0, t4
[Codegen] 0012c293       xori      t0, t0, 0x1
[Codegen] .use Llabel 7ffcb6bc81b0 on 100
[Codegen] 00029063       bne       t0, zero, 0 -> 0x7ffcb6bc7f3c
[Codegen] a20022d3       feq.d     t0, ft0, ft0
[Codegen] .set Llabel 7ffcb6bc81b0 108
[Codegen] 0012c293       xori      t0, t0, 0x1
[Codegen] a2002ed3       feq.d     t4, ft0, ft0
[Codegen] a2002f53       feq.d     t5, ft0, ft0
[Codegen] 01eefeb3       and       t4, t4, t5
[Codegen] 001ece93       xori      t4, t4, 0x1
[Codegen] 01d2e2b3       or        t0, t0, t4
```

And now it's just:
```asm
[Codegen]                                 # LIR=CompareD
[Codegen] a20022d3       feq.d     t0, ft0, ft0
[Codegen] 0012c293       xori      t0, t0, 0x1
```

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

Diffstat:
Mjs/src/jit/riscv64/Assembler-riscv64.h | 2--
Mjs/src/jit/riscv64/MacroAssembler-riscv64.cpp | 150++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------
2 files changed, 92 insertions(+), 60 deletions(-)

diff --git a/js/src/jit/riscv64/Assembler-riscv64.h b/js/src/jit/riscv64/Assembler-riscv64.h @@ -354,8 +354,6 @@ class Assembler : public AssemblerShared, DoubleGreaterThanOrEqualOrUnordered, DoubleLessThanOrUnordered, DoubleLessThanOrEqualOrUnordered, - FIRST_UNORDERED = DoubleUnordered, - LAST_UNORDERED = DoubleLessThanOrEqualOrUnordered }; Register getStackPointer() const { return StackPointer; } diff --git a/js/src/jit/riscv64/MacroAssembler-riscv64.cpp b/js/src/jit/riscv64/MacroAssembler-riscv64.cpp @@ -365,36 +365,58 @@ void MacroAssemblerRiscv64::ma_compareF32(Register rd, DoubleCondition cc, FloatRegister cmp1, FloatRegister cmp2) { switch (cc) { - case DoubleEqualOrUnordered: case DoubleEqual: feq_s(rd, cmp1, cmp2); - break; - case DoubleNotEqualOrUnordered: + return; + case DoubleEqualOrUnordered: { + UseScratchRegisterScope temps(this); + Register scratch = temps.Acquire(); + flt_s(rd, cmp1, cmp2); + flt_s(scratch, cmp2, cmp1); + or_(rd, rd, scratch); + NegateBool(rd, rd); + return; + } case DoubleNotEqual: { - Label done; - CompareIsNanF32(rd, cmp1, cmp2); - ma_branch(&done, Equal, rd, Operand(1)); + UseScratchRegisterScope temps(this); + Register scratch = temps.Acquire(); + flt_s(rd, cmp1, cmp2); + flt_s(scratch, cmp2, cmp1); + or_(rd, rd, scratch); + return; + } + case DoubleNotEqualOrUnordered: feq_s(rd, cmp1, cmp2); - bind(&done); NegateBool(rd, rd); - break; - } - case DoubleLessThanOrUnordered: + return; case DoubleLessThan: flt_s(rd, cmp1, cmp2); - break; - case DoubleGreaterThanOrEqualOrUnordered: + return; + case DoubleLessThanOrUnordered: + fle_s(rd, cmp2, cmp1); + NegateBool(rd, rd); + return; case DoubleGreaterThanOrEqual: fle_s(rd, cmp2, cmp1); - break; - case DoubleLessThanOrEqualOrUnordered: + return; + case DoubleGreaterThanOrEqualOrUnordered: + flt_s(rd, cmp1, cmp2); + NegateBool(rd, rd); + return; case DoubleLessThanOrEqual: fle_s(rd, cmp1, cmp2); - break; - case DoubleGreaterThanOrUnordered: + return; + case DoubleLessThanOrEqualOrUnordered: + flt_s(rd, cmp2, cmp1); + NegateBool(rd, rd); + return; case DoubleGreaterThan: flt_s(rd, cmp2, cmp1); - break; + return; + case DoubleGreaterThanOrUnordered: + fle_s(rd, cmp1, cmp2); + NegateBool(rd, rd); + return; case DoubleOrdered: CompareIsNotNanF32(rd, cmp1, cmp2); return; @@ -402,47 +424,64 @@ void MacroAssemblerRiscv64::ma_compareF32(Register rd, DoubleCondition cc, CompareIsNanF32(rd, cmp1, cmp2); return; } - if (cc >= FIRST_UNORDERED && cc <= LAST_UNORDERED) { - UseScratchRegisterScope temps(this); - Register scratch = temps.Acquire(); - CompareIsNanF32(scratch, cmp1, cmp2); - or_(rd, rd, scratch); - } } void MacroAssemblerRiscv64::ma_compareF64(Register rd, DoubleCondition cc, FloatRegister cmp1, FloatRegister cmp2) { switch (cc) { - case DoubleEqualOrUnordered: case DoubleEqual: feq_d(rd, cmp1, cmp2); - break; - case DoubleNotEqualOrUnordered: + return; + case DoubleEqualOrUnordered: { + UseScratchRegisterScope temps(this); + Register scratch = temps.Acquire(); + flt_d(rd, cmp1, cmp2); + flt_d(scratch, cmp2, cmp1); + or_(rd, rd, scratch); + NegateBool(rd, rd); + return; + } case DoubleNotEqual: { - Label done; - CompareIsNanF64(rd, cmp1, cmp2); - ma_branch(&done, Equal, rd, Operand(1)); + UseScratchRegisterScope temps(this); + Register scratch = temps.Acquire(); + flt_d(rd, cmp1, cmp2); + flt_d(scratch, cmp2, cmp1); + or_(rd, rd, scratch); + return; + } + case DoubleNotEqualOrUnordered: feq_d(rd, cmp1, cmp2); - bind(&done); NegateBool(rd, rd); - } break; - case DoubleLessThanOrUnordered: + return; case DoubleLessThan: flt_d(rd, cmp1, cmp2); - break; - case DoubleGreaterThanOrEqualOrUnordered: + return; + case DoubleLessThanOrUnordered: + fle_d(rd, cmp2, cmp1); + NegateBool(rd, rd); + return; case DoubleGreaterThanOrEqual: fle_d(rd, cmp2, cmp1); - break; - case DoubleLessThanOrEqualOrUnordered: + return; + case DoubleGreaterThanOrEqualOrUnordered: + flt_d(rd, cmp1, cmp2); + NegateBool(rd, rd); + return; case DoubleLessThanOrEqual: fle_d(rd, cmp1, cmp2); - break; - case DoubleGreaterThanOrUnordered: + return; + case DoubleLessThanOrEqualOrUnordered: + flt_d(rd, cmp2, cmp1); + NegateBool(rd, rd); + return; case DoubleGreaterThan: flt_d(rd, cmp2, cmp1); - break; + return; + case DoubleGreaterThanOrUnordered: + fle_d(rd, cmp1, cmp2); + NegateBool(rd, rd); + return; case DoubleOrdered: CompareIsNotNanF64(rd, cmp1, cmp2); return; @@ -450,13 +489,6 @@ void MacroAssemblerRiscv64::ma_compareF64(Register rd, DoubleCondition cc, CompareIsNanF64(rd, cmp1, cmp2); return; } - - if (cc >= FIRST_UNORDERED && cc <= LAST_UNORDERED) { - UseScratchRegisterScope temps(this); - Register scratch = temps.Acquire(); - CompareIsNanF64(scratch, cmp1, cmp2); - or_(rd, rd, scratch); - } } void MacroAssemblerRiscv64Compat::movePtr(Register src, Register dest) { @@ -6201,24 +6233,26 @@ void MacroAssemblerRiscv64::ma_call(ImmPtr dest) { void MacroAssemblerRiscv64::CompareIsNotNanF32(Register rd, FPURegister cmp1, FPURegister cmp2) { - UseScratchRegisterScope temps(this); - BlockTrampolinePoolScope block_trampoline_pool(this, 3); - Register scratch = temps.Acquire(); + feq_s(rd, cmp1, cmp1); // rd <- !isNan(cmp1) + if (cmp1 != cmp2) { + UseScratchRegisterScope temps(this); + Register scratch = temps.Acquire(); - feq_s(rd, cmp1, cmp1); // rd <- !isNan(cmp1) - feq_s(scratch, cmp2, cmp2); // scratch <- !isNaN(cmp2) - ma_and(rd, rd, scratch); // rd <- !isNan(cmp1) && !isNan(cmp2) + feq_s(scratch, cmp2, cmp2); // scratch <- !isNaN(cmp2) + ma_and(rd, rd, scratch); // rd <- !isNan(cmp1) && !isNan(cmp2) + } } void MacroAssemblerRiscv64::CompareIsNotNanF64(Register rd, FPURegister cmp1, FPURegister cmp2) { - UseScratchRegisterScope temps(this); - BlockTrampolinePoolScope block_trampoline_pool(this, 3); - Register scratch = temps.Acquire(); + feq_d(rd, cmp1, cmp1); // rd <- !isNan(cmp1) + if (cmp1 != cmp2) { + UseScratchRegisterScope temps(this); + Register scratch = temps.Acquire(); - feq_d(rd, cmp1, cmp1); // rd <- !isNan(cmp1) - feq_d(scratch, cmp2, cmp2); // scratch <- !isNaN(cmp2) - ma_and(rd, rd, scratch); // rd <- !isNan(cmp1) && !isNan(cmp2) + feq_d(scratch, cmp2, cmp2); // scratch <- !isNaN(cmp2) + ma_and(rd, rd, scratch); // rd <- !isNan(cmp1) && !isNan(cmp2) + } } void MacroAssemblerRiscv64::CompareIsNanF32(Register rd, FPURegister cmp1,