x86/iR5900: Always break rec blocks on SYSCALL/BREAK

In all cases except for GetOsdConfigParam/GetOsdConfigParam2 the HLE
syscall handler will raise the CPU exception, changing the PC.

So, there's no point compiling the rest of the block, especially when it
may contain garbage code. No point checking the PC either, as in almost
every case, it will have changed. So just go straight to the dispatcher.

Note this will have a slight behavioral change - both SYSCALL/BREAK will
check the cycle count for an event test now, whereas before only BREAK
did. But I doubt this'll cause any issues.
This commit is contained in:
Stenzek 2023-01-03 17:17:31 +10:00 committed by refractionpcsx2
parent f48824dec0
commit db4d721b93
1 changed files with 7 additions and 16 deletions

View File

@ -756,15 +756,7 @@ void R5900::Dynarec::OpcodeImpl::recSYSCALL()
EE::Profiler.EmitOp(eeOpcode::SYSCALL);
recCall(R5900::Interpreter::OpcodeImpl::SYSCALL);
xCMP(ptr32[&cpuRegs.pc], pc);
j8Ptr[0] = JE8(0);
xADD(ptr32[&cpuRegs.cycle], scaleblockcycles());
// Note: technically the address is 0x8000_0180 (or 0x180)
// (if CPU is booted)
xJMP((void*)DispatcherReg);
x86SetJ8(j8Ptr[0]);
//g_branch = 2;
g_branch = 2; // Indirect branch with event check.
}
////////////////////////////////////////////////////
@ -773,13 +765,7 @@ void R5900::Dynarec::OpcodeImpl::recBREAK()
EE::Profiler.EmitOp(eeOpcode::BREAK);
recCall(R5900::Interpreter::OpcodeImpl::BREAK);
xCMP(ptr32[&cpuRegs.pc], pc);
j8Ptr[0] = JE8(0);
xADD(ptr32[&cpuRegs.cycle], scaleblockcycles());
xJMP((void*)DispatcherEvent);
x86SetJ8(j8Ptr[0]);
//g_branch = 2;
g_branch = 2; // Indirect branch with event check.
}
// Size is in dwords (4 bytes)
@ -2334,6 +2320,11 @@ static void recRecompile(const u32 startpc)
s_nEndBlock = i + 8;
goto StartRecomp;
}
else if (_Funct_ == 12 || _Funct_ == 13) // SYSCALL, BREAK
{
s_nEndBlock = i + 4; // No delay slot.
goto StartRecomp;
}
break;
case 1: // regimm