Jit: Raise program exception on floating point exceptions
This is done entirely through interpreter fallbacks. It would probably be possible to implement this using host exception handlers instead, but I think it would be a lot of complexity for a rarely used feature, so let's not do it for now. For performance reasons, there are two settings for this feature: One setting which does enables just what True Crime: New York City needs and one setting which enables it all. The latter makes almost all float instructions fall back to the interpreter.
This commit is contained in:
1 parent
7f7748e181
commit
9f525d69c8
24 files changed
+216
-88
No files matched your search
@@ -58,7 +58,7 @@ void CachedInterpreter::Init()
|
||||
jo.enableBlocklink = false;
|
||||
|
||||
m_block_cache.Init();
|
||||
UpdateMemoryOptions();
|
||||
UpdateMemoryAndExceptionOptions();
|
||||
|
||||
code_block.m_stats = &js.st;
|
||||
code_block.m_gpa = &js.gpa;
|
||||
@@ -180,6 +180,17 @@ static bool CheckDSI(u32 data)
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool CheckProgramException(u32 data)
|
||||
{
|
||||
if (PowerPC::ppcState.Exceptions & EXCEPTION_PROGRAM)
|
||||
{
|
||||
PowerPC::CheckExceptions();
|
||||
PowerPC::ppcState.downcount -= data;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool CheckBreakpoint(u32 data)
|
||||
{
|
||||
PowerPC::CheckBreakPoints();
|
||||
@@ -267,26 +278,26 @@ void CachedInterpreter::Jit(u32 address)
|
||||
const bool check_fpu = (op.opinfo->flags & FL_USE_FPU) && !js.firstFPInstructionFound;
|
||||
const bool endblock = (op.opinfo->flags & FL_ENDBLOCK) != 0;
|
||||
const bool memcheck = (op.opinfo->flags & FL_LOADSTORE) && jo.memcheck;
|
||||
const bool check_program_exception = !endblock && ShouldHandleFPExceptionForInstruction(&op);
|
||||
const bool idle_loop = op.branchIsIdleLoop;
|
||||
|
||||
if (breakpoint)
|
||||
{
|
||||
if (breakpoint || check_fpu || endblock || memcheck || check_program_exception)
|
||||
m_code.emplace_back(WritePC, op.address);
|
||||
|
||||
if (breakpoint)
|
||||
m_code.emplace_back(CheckBreakpoint, js.downcountAmount);
|
||||
}
|
||||
|
||||
if (check_fpu)
|
||||
{
|
||||
m_code.emplace_back(WritePC, op.address);
|
||||
m_code.emplace_back(CheckFPU, js.downcountAmount);
|
||||
js.firstFPInstructionFound = true;
|
||||
}
|
||||
|
||||
if (endblock || memcheck)
|
||||
m_code.emplace_back(WritePC, op.address);
|
||||
m_code.emplace_back(PPCTables::GetInterpreterOp(op.inst), op.inst);
|
||||
if (memcheck)
|
||||
m_code.emplace_back(CheckDSI, js.downcountAmount);
|
||||
if (check_program_exception)
|
||||
m_code.emplace_back(CheckProgramException, js.downcountAmount);
|
||||
if (idle_loop)
|
||||
m_code.emplace_back(CheckIdle, js.blockStart);
|
||||
if (endblock)
|
||||
@@ -316,5 +327,5 @@ void CachedInterpreter::ClearCache()
|
||||
{
|
||||
m_code.clear();
|
||||
m_block_cache.Clear();
|
||||
UpdateMemoryOptions();
|
||||
UpdateMemoryAndExceptionOptions();
|
||||
}
|
||||
Reference in new issue
Block a user