From fe1fa765f71cf0685e26d086b4078c798a04225f Mon Sep 17 00:00:00 2001 From: Stenzek Date: Thu, 19 Dec 2024 18:15:15 +1000 Subject: [PATCH] CPU/Recompiler: Don't back up value to stack in mtc0 Fixes misaligned stack that could crash in log messages. --- src/core/cpu_recompiler_arm32.cpp | 10 +--------- src/core/cpu_recompiler_arm64.cpp | 12 +----------- src/core/cpu_recompiler_riscv64.cpp | 5 +---- src/core/cpu_recompiler_x64.cpp | 7 ++----- 4 files changed, 5 insertions(+), 29 deletions(-) diff --git a/src/core/cpu_recompiler_arm32.cpp b/src/core/cpu_recompiler_arm32.cpp index 9228956192..2e6220ac87 100644 --- a/src/core/cpu_recompiler_arm32.cpp +++ b/src/core/cpu_recompiler_arm32.cpp @@ -31,10 +31,6 @@ LOG_CHANNEL(Recompiler); #define PTR(x) vixl::aarch32::MemOperand(RSTATE, (((u8*)(x)) - ((u8*)&g_state))) #define RMEMBASE vixl::aarch32::r3 -static constexpr u32 FUNCTION_CALLEE_SAVED_SPACE_RESERVE = 80; // 8 registers -static constexpr u32 FUNCTION_CALLER_SAVED_SPACE_RESERVE = 144; // 18 registers -> 224 bytes -static constexpr u32 FUNCTION_STACK_SIZE = FUNCTION_CALLEE_SAVED_SPACE_RESERVE + FUNCTION_CALLER_SAVED_SPACE_RESERVE; - #define RRET vixl::aarch32::r0 #define RRETHI vixl::aarch32::r1 #define RARG1 vixl::aarch32::r0 @@ -266,9 +262,6 @@ u32 CPU::CodeCache::EmitASMFunctions(void* code, u32 code_size) g_enter_recompiler = armAsm->GetCursorAddress(); { - // reserve some space for saving caller-saved registers - armAsm->sub(sp, sp, FUNCTION_STACK_SIZE); - // Need the CPU state for basically everything :-) armMoveAddressToReg(armAsm, RSTATE, &g_state); } @@ -2273,9 +2266,8 @@ void CPU::ARM32Recompiler::Compile_mtc0(CompileFlags cf) Flush(FLUSH_FOR_C_CALL); SwitchToFarCodeIfBitSet(changed_bits, 16); - armAsm->push(RegisterList(RARG1)); EmitCall(reinterpret_cast(&CPU::UpdateMemoryPointers)); - armAsm->pop(RegisterList(RARG1)); + armAsm->ldr(RARG1, PTR(ptr)); // reload value for interrupt test below if (CodeCache::IsUsingFastmem() && m_block->HasFlag(CodeCache::BlockFlags::ContainsLoadStoreInstructions) && IsHostRegAllocated(RMEMBASE.GetCode())) { diff --git a/src/core/cpu_recompiler_arm64.cpp b/src/core/cpu_recompiler_arm64.cpp index fb40f307d7..6bfd8a1f35 100644 --- a/src/core/cpu_recompiler_arm64.cpp +++ b/src/core/cpu_recompiler_arm64.cpp @@ -28,10 +28,6 @@ LOG_CHANNEL(Recompiler); #define PTR(x) vixl::aarch64::MemOperand(RSTATE, (((u8*)(x)) - ((u8*)&g_state))) -static constexpr u64 FUNCTION_CALLEE_SAVED_SPACE_RESERVE = 80; // 8 registers -static constexpr u64 FUNCTION_CALLER_SAVED_SPACE_RESERVE = 144; // 18 registers -> 224 bytes -static constexpr u64 FUNCTION_STACK_SIZE = FUNCTION_CALLEE_SAVED_SPACE_RESERVE + FUNCTION_CALLER_SAVED_SPACE_RESERVE; - #define RWRET vixl::aarch64::w0 #define RXRET vixl::aarch64::x0 #define RWARG1 vixl::aarch64::w0 @@ -448,9 +444,6 @@ u32 CPU::CodeCache::EmitASMFunctions(void* code, u32 code_size) g_enter_recompiler = armAsm->GetCursorAddress(); { - // reserve some space for saving caller-saved registers - armAsm->sub(sp, sp, FUNCTION_STACK_SIZE); - // Need the CPU state for basically everything :-) armMoveAddressToReg(armAsm, RSTATE, &g_state); @@ -2436,11 +2429,8 @@ void CPU::ARM64Recompiler::Compile_mtc0(CompileFlags cf) Flush(FLUSH_FOR_C_CALL); SwitchToFarCodeIfBitSet(changed_bits, 16); - armAsm->sub(sp, sp, 16); - armAsm->str(RWARG1, MemOperand(sp)); EmitCall(reinterpret_cast(&CPU::UpdateMemoryPointers)); - armAsm->ldr(RWARG1, MemOperand(sp)); - armAsm->add(sp, sp, 16); + armAsm->ldr(RWARG1, PTR(ptr)); // reload value for interrupt test below armAsm->ldr(RMEMBASE, PTR(&g_state.fastmem_base)); SwitchToNearCode(true); diff --git a/src/core/cpu_recompiler_riscv64.cpp b/src/core/cpu_recompiler_riscv64.cpp index f116405795..f545752e8d 100644 --- a/src/core/cpu_recompiler_riscv64.cpp +++ b/src/core/cpu_recompiler_riscv64.cpp @@ -2286,11 +2286,8 @@ void CPU::RISCV64Recompiler::Compile_mtc0(CompileFlags cf) rvAsm->SRLIW(RSCRATCH, changed_bits, 16); rvAsm->ANDI(RSCRATCH, RSCRATCH, 1); SwitchToFarCode(true, &Assembler::BEQ, RSCRATCH, zero); - rvAsm->ADDI(sp, sp, -16); - rvAsm->SW(RARG1, 0, sp); EmitCall(reinterpret_cast(&CPU::UpdateMemoryPointers)); - rvAsm->LW(RARG1, 0, sp); - rvAsm->ADDI(sp, sp, 16); + rvAsm->LW(new_value, PTR(ptr)); rvAsm->LD(RMEMBASE, PTR(&g_state.fastmem_base)); SwitchToNearCode(true); diff --git a/src/core/cpu_recompiler_x64.cpp b/src/core/cpu_recompiler_x64.cpp index 2fdf108d1a..9be9c7c21e 100644 --- a/src/core/cpu_recompiler_x64.cpp +++ b/src/core/cpu_recompiler_x64.cpp @@ -2243,11 +2243,8 @@ void CPU::X64Recompiler::Compile_mtc0(CompileFlags cf) cg->test(changed_bits, 1u << 16); SwitchToFarCode(true, &CodeGenerator::jnz); - cg->mov(cg->dword[cg->rsp], RWARG2); - cg->sub(cg->rsp, STACK_SHADOW_SIZE + 8); cg->call(&CPU::UpdateMemoryPointers); - cg->add(cg->rsp, STACK_SHADOW_SIZE + 8); - cg->mov(RWARG2, cg->dword[cg->rsp]); + cg->mov(RWARG2, cg->dword[PTR(ptr)]); // reload value for interrupt test below cg->mov(RMEMBASE, cg->qword[PTR(&g_state.fastmem_base)]); SwitchToNearCode(true); @@ -2475,7 +2472,7 @@ u32 CPU::Recompiler::CompileLoadStoreThunk(void* thunk_code, u32 thunk_space, vo num_gprs++; } - const u32 stack_size = (((num_gprs + 1) & ~1u) * GPR_SIZE) + STACK_SHADOW_SIZE; + const u32 stack_size = (((num_gprs + 1) & ~1u) * GPR_SIZE); if (stack_size > 0) {