commit b3e3e9c8efb26cf0ea4001bf1ade985673754f27
parent ab14aa70c09eb5cdd72535cc41f3b29a6acfda85
Author: Xuan Chen <henry.chen@oss.cipunited.com>
Date: Mon, 24 Nov 2025 12:24:53 +0000
Bug 2001289 - Part 2: [mips64] Implement js::wasm::CallOnMainStack. r=anba
This patch completes WASM JSPI support for both real and simulated mips64.
The inline assembly doesn't directly handle the delay slot because the
assembler reorders affected instructions by default, unless the `noreorder`
directive is set.
Differential Revision: https://phabricator.services.mozilla.com/D273766
Diffstat:
2 files changed, 50 insertions(+), 5 deletions(-)
diff --git a/js/src/wasm/WasmPI.cpp b/js/src/wasm/WasmPI.cpp
@@ -49,6 +49,8 @@
# include "jit/riscv64/Simulator-riscv64.h"
#elif defined(JS_CODEGEN_LOONG64)
# include "jit/loong64/Simulator-loong64.h"
+#elif defined(JS_CODEGEN_MIPS64)
+# include "jit/mips64/Simulator-mips64.h"
#endif
#ifdef XP_WIN
@@ -133,7 +135,8 @@ void SuspenderObjectData::switchSimulatorToSuspendable() {
Simulator::Current()->set_register(Simulator::fp, (int)suspendableFP_);
}
-# elif defined(JS_SIMULATOR_RISCV64) || defined(JS_SIMULATOR_LOONG64)
+# elif defined(JS_SIMULATOR_RISCV64) || defined(JS_SIMULATOR_LOONG64) || \
+ defined(JS_SIMULATOR_MIPS64)
void SuspenderObjectData::switchSimulatorToMain() {
suspendableSP_ = (void*)Simulator::Current()->getRegister(Simulator::sp);
suspendableFP_ = (void*)Simulator::Current()->getRegister(Simulator::fp);
@@ -573,8 +576,9 @@ bool CallOnMainStack(JSContext* cx, CallOnMainStackFn fn, void* data) {
MOZ_RELEASE_ASSERT(suspender->data()->suspendedBy() == nullptr);
# ifdef JS_SIMULATOR
-# if defined(JS_SIMULATOR_ARM64) || defined(JS_SIMULATOR_ARM) || \
- defined(JS_SIMULATOR_RISCV64) || defined(JS_SIMULATOR_LOONG64)
+# if defined(JS_SIMULATOR_ARM64) || defined(JS_SIMULATOR_ARM) || \
+ defined(JS_SIMULATOR_RISCV64) || defined(JS_SIMULATOR_LOONG64) || \
+ defined(JS_SIMULATOR_MIPS64)
// The simulator is using its own stack, however switching is needed for
// virtual registers.
stacks->switchSimulatorToMain();
@@ -854,6 +858,46 @@ bool CallOnMainStack(JSContext* cx, CallOnMainStackFn fn, void* data) {
: "ra", "a0", "a3", CALLER_SAVED_REGS, "cc", "memory")
INLINED_ASM(24, 32, 40, 48);
+# elif defined(__mips64)
+# define CALLER_SAVED_REGS \
+ "at", "v0", "v1", \
+ "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", \
+ "t0", "t1", "t2", "t3", /* Assemblers don't recognize t4-t7 */ \
+ "t8", "t9", "ra", "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", \
+ "$f6", "$f7", "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", \
+ "$f14", "$f15", "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", \
+ "$f22", "$f23"
+# define INLINED_ASM(MAIN_FP, MAIN_SP, SUSPENDABLE_FP, SUSPENDABLE_SP) \
+ CHECK_OFFSETS(MAIN_FP, MAIN_SP, SUSPENDABLE_FP, SUSPENDABLE_SP); \
+ asm volatile( \
+ "\n move $a0, %1" \
+ "\n move $t9, %2" /* PIC function entry */ \
+ "\n sd $fp, " #SUSPENDABLE_FP "($a0)" \
+ "\n sd $sp, " #SUSPENDABLE_SP "($a0)" \
+ \
+ "\n ld $fp, " #MAIN_FP "($a0)" \
+ "\n ld $sp, " #MAIN_SP "($a0)" \
+ \
+ "\n daddiu $sp, $sp, -16" \
+ "\n sd $a0, 8($sp)" \
+ \
+ "\n move $a0, %3" \
+ "\n jalr $t9" \
+ \
+ "\n ld $a3, 8($sp)" \
+ "\n daddiu $sp, $sp, 16" \
+ \
+ "\n sd $fp, " #MAIN_FP "($a3)" \
+ "\n sd $sp, " #MAIN_SP "($a3)" \
+ \
+ "\n ld $fp, " #SUSPENDABLE_FP "($a3)" \
+ "\n ld $sp, " #SUSPENDABLE_SP "($a3)" \
+ "\n move %0, $v0" \
+ : "=r"(res) \
+ : "r"(stacks), "r"(fn), "r"(data) \
+ : CALLER_SAVED_REGS, "cc", "memory")
+ INLINED_ASM(24, 32, 40, 48);
+
# else
MOZ_CRASH("Not supported for this platform");
# endif
diff --git a/js/src/wasm/WasmPI.h b/js/src/wasm/WasmPI.h
@@ -198,8 +198,9 @@ class SuspenderObjectData
void restoreTIBStackFields();
#endif
-#if defined(JS_SIMULATOR_ARM64) || defined(JS_SIMULATOR_ARM) || \
- defined(JS_SIMULATOR_RISCV64) || defined(JS_SIMULATOR_LOONG64)
+#if defined(JS_SIMULATOR_ARM64) || defined(JS_SIMULATOR_ARM) || \
+ defined(JS_SIMULATOR_RISCV64) || defined(JS_SIMULATOR_LOONG64) || \
+ defined(JS_SIMULATOR_MIPS64)
void switchSimulatorToMain();
void switchSimulatorToSuspendable();
#endif