From 91dff7cb3f8de43d032f24ae6b573832254b5e4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 19 Sep 2026 11:14:08 -0600 Subject: [PATCH] LoongArch64: fix QuickCallFunctionR passing the argument in a vector register MOVE(LoongArch64Reg::X4, arg) targets X4, which is an LASX 256-bit vector register (0x64), not a0. The LP64D ABI puts the first integer argument in a0, which is R4. This is not a corner case: GenerateFixedCode uses QuickCallFunctionR for CoreTiming::Advance, so the emitter asserted ("DJK instruction rd must be GPR") while building the dispatcher, before a single block was compiled. The LoongArch native JIT could not start at all. Found by running the loongarch64 cross build under qemu-user. Co-Authored-By: Claude Opus 5 (1M context) --- Common/LoongArch64Emitter.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Common/LoongArch64Emitter.h b/Common/LoongArch64Emitter.h index 134b5de61d..d5abda3809 100644 --- a/Common/LoongArch64Emitter.h +++ b/Common/LoongArch64Emitter.h @@ -166,7 +166,8 @@ public: QuickCallFunction((const u8 *)func, scratchreg); } void QuickCallFunctionR(const u8 *func, LoongArch64Reg arg, LoongArch64Reg scratchreg = R_RA) { - MOVE(LoongArch64Reg::X4, arg); + // The first integer argument goes in a0, which is R4 - X4 is an LASX vector register. + MOVE(LoongArch64Reg::R4, arg); QuickJump(scratchreg, R_RA, func); } template