diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index d8fb12c3ec..1d9d336a2a 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -671,7 +671,6 @@ void PPUThread::FastCall2(u32 addr, u32 rtoc) m_status = Running; PC = addr; - GPR[1] -= 0x70; // create stack frame reserved area GPR[2] = rtoc; LR = Emu.GetCPUThreadStop(); SetCurrentNamedThread(this); @@ -681,7 +680,13 @@ void PPUThread::FastCall2(u32 addr, u32 rtoc) m_status = old_status; PC = old_PC; - GPR[1] = old_stack; // TODO: error check instead of blind assignment? GPR[1] shouldn't change + + if (GPR[1] != old_stack) // GPR[1] shouldn't change + { + LOG_ERROR(PPU, "PPUThread::FastCall2(0x%x,0x%x): stack inconsistency (SP=0x%llx, old=0x%llx)", addr, rtoc, GPR[1], old_stack); + GPR[1] = old_stack; + } + GPR[2] = old_rtoc; LR = old_LR; SetCurrentNamedThread(old_thread); diff --git a/rpcs3/Emu/Memory/vm.cpp b/rpcs3/Emu/Memory/vm.cpp index dc32c017ac..c145c3bf57 100644 --- a/rpcs3/Emu/Memory/vm.cpp +++ b/rpcs3/Emu/Memory/vm.cpp @@ -628,27 +628,25 @@ namespace vm u32 stack_push(CPUThread& CPU, u32 size, u32 align_v, u32& old_pos) { - assert(align_v); - switch (CPU.GetType()) { case CPU_THREAD_PPU: { - PPUThread& PPU = static_cast(CPU); + PPUThread& context = static_cast(CPU); - old_pos = vm::cast(PPU.GPR[1], "SP"); - PPU.GPR[1] -= align(size, 8); // room minimal possible size - PPU.GPR[1] &= ~(align_v - 1); // fix stack alignment + old_pos = vm::cast(context.GPR[1], "SP"); + context.GPR[1] -= align(size, 8); // room minimal possible size + context.GPR[1] &= ~(align_v - 1); // fix stack alignment - if (PPU.GPR[1] < CPU.GetStackAddr()) + if (context.GPR[1] < CPU.GetStackAddr()) { - // stack overflow - PPU.GPR[1] = old_pos; + LOG_ERROR(PPU, "vm::stack_push(0x%x,%d): stack overflow (SP=0x%llx, stack=*0x%x)", size, align_v, context.GPR[1], CPU.GetStackAddr()); + context.GPR[1] = old_pos; return 0; } else { - return (u32)PPU.GPR[1]; + return static_cast(context.GPR[1]); } } @@ -669,7 +667,7 @@ namespace vm if (context.SP < CPU.GetStackAddr()) { - // stack overflow + LOG_ERROR(ARMv7, "vm::stack_push(0x%x,%d): stack overflow (SP=0x%x, stack=*0x%x)", size, align_v, context.SP, CPU.GetStackAddr()); context.SP = old_pos; return 0; } @@ -693,10 +691,14 @@ namespace vm { case CPU_THREAD_PPU: { - PPUThread& PPU = static_cast(CPU); + PPUThread& context = static_cast(CPU); - assert(PPU.GPR[1] == addr); - PPU.GPR[1] = old_pos; + if (context.GPR[1] != addr) + { + LOG_ERROR(PPU, "vm::stack_pop(*0x%x,*0x%x): stack inconsistency (SP=0x%llx)", addr, old_pos, context.GPR[1]); + } + + context.GPR[1] = old_pos; return; } @@ -711,7 +713,11 @@ namespace vm { ARMv7Context& context = static_cast(CPU).context; - assert(context.SP == addr); + if (context.SP != addr) + { + LOG_ERROR(ARMv7, "vm::stack_pop(*0x%x,*0x%x): stack inconsistency (SP=0x%x)", addr, old_pos, context.SP); + } + context.SP = old_pos; return; } diff --git a/rpcs3/Emu/SysCalls/CB_FUNC.h b/rpcs3/Emu/SysCalls/CB_FUNC.h index 2fb0a99a70..13203e43dc 100644 --- a/rpcs3/Emu/SysCalls/CB_FUNC.h +++ b/rpcs3/Emu/SysCalls/CB_FUNC.h @@ -132,10 +132,7 @@ namespace cb_detail { __forceinline static RT call(PPUThread& CPU, u32 pc, u32 rtoc, T... args) { - const bool stack = _bind_func_args<0, 0, 0, T...>(CPU, args...); - if (stack) CPU.GPR[1] -= FIXED_STACK_FRAME_SIZE; - CPU.FastCall2(pc, rtoc); - if (stack) CPU.GPR[1] += FIXED_STACK_FRAME_SIZE; + _func_caller::call(CPU, pc, rtoc, args...); static_assert(!std::is_pointer::value, "Invalid callback result type (pointer)"); static_assert(!std::is_reference::value, "Invalid callback result type (reference)"); @@ -154,7 +151,9 @@ namespace cb_detail { const bool stack = _bind_func_args<0, 0, 0, T...>(CPU, args...); if (stack) CPU.GPR[1] -= FIXED_STACK_FRAME_SIZE; + CPU.GPR[1] -= 0x70; // create reserved area CPU.FastCall2(pc, rtoc); + CPU.GPR[1] += 0x70; if (stack) CPU.GPR[1] += FIXED_STACK_FRAME_SIZE; } }; diff --git a/rpcs3/Emu/SysCalls/Modules.cpp b/rpcs3/Emu/SysCalls/Modules.cpp index c2cb8f2e0d..0e9f3561f9 100644 --- a/rpcs3/Emu/SysCalls/Modules.cpp +++ b/rpcs3/Emu/SysCalls/Modules.cpp @@ -106,12 +106,16 @@ void execute_ppu_func_by_index(PPUThread& CPU, u32 index) { // call LLE function if available + const auto data = vm::get_ptr>(func->lle_func.addr()); + const u32 pc = data[0]; + const u32 rtoc = data[1]; + if (Ini.HLELogging.GetValue()) { LOG_NOTICE(HLE, "LLE function called: %s", SysCalls::GetFuncName(func->id)); } - - func->lle_func(CPU); + + CPU.FastCall2(pc, rtoc); if (Ini.HLELogging.GetValue()) {