From 2755d9941cb364e75a8b00c554daeb3412c034ab Mon Sep 17 00:00:00 2001 From: sguo35 Date: Sat, 9 Jul 2022 23:31:37 -0700 Subject: [PATCH] ppu: fix a bug where arm64 sp wasn't being saved ASMJIT can silently fail and drop instructions when invalid operations are performed (e.g. loading/storing sp). Explicitly move sp to a gp register before doing loads/stores to fix this. --- rpcs3/Emu/Cell/PPUThread.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index 4c8e20f682..acd8c6077d 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -287,7 +287,9 @@ const auto ppu_gateway = build_function_asm("ppu_gateway", // Save sp for native longjmp emulation Label native_sp_offset = c.newLabel(); c.ldr(a64::x10, arm::Mem(native_sp_offset)); - c.str(a64::sp, arm::Mem(args[0], a64::x10)); + // sp not allowed to be used in load/stores directly + c.mov(a64::x15, a64::sp); + c.str(a64::x15, arm::Mem(args[0], a64::x10)); // Load REG_Base - use absolute jump target to bypass rel jmp range limits Label exec_addr = c.newLabel(); @@ -342,7 +344,8 @@ const auto ppu_gateway = build_function_asm("ppu_gateway", // Restore stack ptr c.ldr(a64::x10, arm::Mem(native_sp_offset)); - c.ldr(a64::sp, arm::Mem(args[0], a64::x10)); + c.ldr(a64::x15, arm::Mem(a64::x20, a64::x10)); + c.mov(a64::sp, a64::x15); // Restore registers from the stack c.ldp(a64::x18, a64::x19, arm::Mem(a64::sp)); c.ldp(a64::x20, a64::x21, arm::Mem(a64::sp, 16));