summaryrefslogtreecommitdiffstats
path: root/libs/wpewebkit/patches/146-JavaScriptCore-Wasm-BBQ-sext-i32-ccall-args-RISCV64.patch
blob: 8f7e6571e0113ad170e887857d01ec7e5d765c01 (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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
--- a/Source/JavaScriptCore/wasm/WasmBBQJIT.h
+++ b/Source/JavaScriptCore/wasm/WasmBBQJIT.h
@@ -2032,6 +2032,12 @@ public:
     template<typename Args>
     void saveValuesAcrossCallAndPassArguments(const Args& arguments, const CallInformation& callInfo, const TypeDefinition& signature);
 
+    // On RISC-V the psABI requires 32-bit integer arguments to be sign-extended
+    // in their 64-bit argument registers; BBQ otherwise zero-extends them when
+    // loading from canonical i32 slots (lwu). Emit sext.w on any I32 arg that
+    // ends up in a register. No-op on other architectures.
+    void emitSignExtendI32ArgsForCCall(const CallInformation& callInfo, const TypeDefinition& signature);
+
     void slowPathSpillBindings(const RegisterBindings& bindings);
     void slowPathRestoreBindings(const RegisterBindings&);
     void restoreValuesAfterCall(const CallInformation& callInfo);
--- a/Source/JavaScriptCore/wasm/WasmBBQJIT.cpp
+++ b/Source/JavaScriptCore/wasm/WasmBBQJIT.cpp
@@ -4286,6 +4286,26 @@ void BBQJIT::restoreValuesAfterCall(cons
     // whenever they are next used.
 }
 
+void BBQJIT::emitSignExtendI32ArgsForCCall(const CallInformation& callInfo, const TypeDefinition& signature)
+{
+#if CPU(RISCV64)
+    auto* fn = signature.as<FunctionSignature>();
+    for (size_t i = 0; i < callInfo.params.size(); ++i) {
+        auto type = fn->argumentType(i);
+        if (type.kind != TypeKind::I32)
+            continue;
+        Location loc = Location::fromArgumentLocation(callInfo.params[i], type.kind);
+        if (!loc.isGPR())
+            continue;
+        // sext.w rd, rs lowers via signExtend32To64 -> rv_addiw rd, rs, 0
+        m_jit.signExtend32To64(loc.asGPR(), loc.asGPR());
+    }
+#else
+    UNUSED_PARAM(callInfo);
+    UNUSED_PARAM(signature);
+#endif
+}
+
 template<size_t N>
 void BBQJIT::returnValuesFromCall(Vector<Value, N>& results, const FunctionSignature& functionType, const CallInformation& callInfo)
 {
--- a/Source/JavaScriptCore/wasm/WasmBBQJIT64.h
+++ b/Source/JavaScriptCore/wasm/WasmBBQJIT64.h
@@ -505,6 +505,7 @@ void BBQJIT::emitCCall(Func function, co
     // Preserve caller-saved registers and other info
     prepareForExceptions();
     saveValuesAcrossCallAndPassArguments(arguments, callInfo, *functionType);
+    emitSignExtendI32ArgsForCCall(callInfo, *functionType);
 
     // Materialize address of native function and call register
     void* taggedFunctionPtr = tagCFunctionPtr<void*, OperationPtrTag>(function);
@@ -534,6 +535,7 @@ void BBQJIT::emitCCall(Func function, co
     // Preserve caller-saved registers and other info
     prepareForExceptions();
     saveValuesAcrossCallAndPassArguments(arguments, callInfo, *functionType);
+    emitSignExtendI32ArgsForCCall(callInfo, *functionType);
 
     // Materialize address of native function and call register
     void* taggedFunctionPtr = tagCFunctionPtr<void*, OperationPtrTag>(function);