summaryrefslogtreecommitdiffstats
path: root/libs/wpewebkit/patches/153-JavaScriptCore-RISCV64-FPR-scratch-fix.patch
blob: a0ea014ed7638ad4a934867d3be57ba6b9403dbe (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
From: Daniel Golle <daniel@makrotopia.org>
Subject: [PATCH] JavaScriptCore: RISCV64: fix nonPreservedNonArgumentFPR0 aliasing argumentFPR1

On RISCV64, FPRInfo declared

    nonPreservedNonArgumentFPR0 = RISCV64Registers::f11

but f11 is fa1 = argumentFPR1. BBQJIT pins wasmScratchFPR to
nonPreservedNonArgumentFPR0 and uses it to materialise f32/f64
immediates for binary float comparisons (emitCompareF32/F64). When the
non-immediate operand is bound to fa1 (e.g. wasm result/argument 1),
emitMoveConst into the "scratch" register silently overwrites that
value before the comparison runs.

Symptom: spec-tests/wasm/stress multi-return tests that compare each
returned f32/f64 against a constant fail at the fa1 slot:

  wasm-wasm-call-many-return-types-on-stack-no-args.js
  wasm-wasm-call-indirect-many-return-types-on-stack.js
  wasm-js-call-many-return-types-on-stack-no-args.js

The bug is not about spill pressure; it is the scratch FPR aliasing an
argument/return FPR for any value bound to fa1.

Use f0 (ft0) -- a RISC-V caller-saved temporary outside the f10..f17
argument/return set -- matching the pattern used by ARM64 (q16) and
X86_64 (xmm8).

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
--- a/Source/JavaScriptCore/jit/FPRInfo.h
+++ b/Source/JavaScriptCore/jit/FPRInfo.h
@@ -366,7 +366,7 @@ public:
     static constexpr FPRReg argumentFPR7 = RISCV64Registers::f17; // fpRegT7
 
     static constexpr FPRReg returnValueFPR = RISCV64Registers::f10; // fpRegT0
-    static constexpr FPRReg nonPreservedNonArgumentFPR0 = RISCV64Registers::f11;
+    static constexpr FPRReg nonPreservedNonArgumentFPR0 = RISCV64Registers::f0;
 
     static FPRReg toRegister(unsigned index)
     {