diff --git a/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp b/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp index a6cbc9cf1d..306b1a3ba2 100644 --- a/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp +++ b/rpcs3/Emu/Cell/PPULLVMRecompiler.cpp @@ -609,7 +609,7 @@ bool ppu_recompiler_llvm::CPUHybridDecoderRecompiler::PollStatus(PPUThread * ppu catch (...) { ppu_state->pending_exception = std::current_exception(); - return ExecutionStatus::ExecutionStatusPropagateException; + return true; } } #endif // LLVM_AVAILABLE diff --git a/rpcs3/Emu/Cell/PPULLVMRecompilerCore.cpp b/rpcs3/Emu/Cell/PPULLVMRecompilerCore.cpp index 6596cc3bcc..d3af52b2e9 100644 --- a/rpcs3/Emu/Cell/PPULLVMRecompilerCore.cpp +++ b/rpcs3/Emu/Cell/PPULLVMRecompilerCore.cpp @@ -1754,9 +1754,8 @@ void Compiler::BC(u32 bo, u32 bi, s32 bd, u32 aa, u32 lk) { -static u32 -wrappedExecutePPUFuncByIndex(PPUThread &CPU, u32 index) -{ +static u32 +wrappedExecutePPUFuncByIndex(PPUThread &CPU, u32 index) noexcept { try { execute_ppu_func_by_index(CPU, index); @@ -1785,7 +1784,7 @@ void Compiler::HACK(u32 index) { } } -static u32 wrappedDoSyscall(PPUThread &CPU, u64 code) { +static u32 wrappedDoSyscall(PPUThread &CPU, u64 code) noexcept { try { SysCalls::DoSyscall(CPU, code); @@ -1801,7 +1800,16 @@ static u32 wrappedDoSyscall(PPUThread &CPU, u64 code) { void Compiler::SC(u32 lev) { switch (lev) { case 0: - Call("wrappedDoSyscall", &wrappedDoSyscall, m_state.args[CompileTaskState::Args::State], GetGpr(11)); + { + llvm::Value *status = Call("wrappedDoSyscall", &wrappedDoSyscall, m_state.args[CompileTaskState::Args::State], GetGpr(11)); + llvm::BasicBlock *cputhreadexitblock = GetBasicBlockFromAddress(m_state.current_instruction_address, "early_exit"); + llvm::Value *isCPUThreadExit = m_ir_builder->CreateICmpEQ(status, m_ir_builder->getInt32(ExecutionStatus::ExecutionStatusPropagateException)); + llvm::BasicBlock *normal_execution = GetBasicBlockFromAddress(m_state.current_instruction_address, "normal_execution"); + m_ir_builder->CreateCondBr(isCPUThreadExit, cputhreadexitblock, normal_execution); + m_ir_builder->SetInsertPoint(cputhreadexitblock); + m_ir_builder->CreateRet(m_ir_builder->getInt32(ExecutionStatus::ExecutionStatusPropagateException)); + m_ir_builder->SetInsertPoint(normal_execution); + } break; case 3: Call("PPUThread.FastStop", &PPUThread::fast_stop, m_state.args[CompileTaskState::Args::State]);