Add support for DSI exceptions to CachedInterpreter.
Should be straightforward. Maybe useful for the purpose of testing.
This commit is contained in:
parent
758e6406cd
commit
ca511640a5
|
@ -20,6 +20,7 @@ void CachedInterpreter::Init()
|
||||||
jo.enableBlocklink = false;
|
jo.enableBlocklink = false;
|
||||||
|
|
||||||
JitBaseBlockCache::Init();
|
JitBaseBlockCache::Init();
|
||||||
|
UpdateMemoryOptions();
|
||||||
|
|
||||||
code_block.m_stats = &js.st;
|
code_block.m_stats = &js.st;
|
||||||
code_block.m_gpa = &js.gpa;
|
code_block.m_gpa = &js.gpa;
|
||||||
|
@ -82,14 +83,30 @@ static void WritePC(UGeckoInstruction data)
|
||||||
NPC = data.hex + 4;
|
NPC = data.hex + 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void WriteBrokenBlockNPC(UGeckoInstruction data)
|
||||||
|
{
|
||||||
|
NPC = data.hex;
|
||||||
|
}
|
||||||
|
|
||||||
static bool CheckFPU(u32 data)
|
static bool CheckFPU(u32 data)
|
||||||
{
|
{
|
||||||
UReg_MSR& msr = (UReg_MSR&)MSR;
|
UReg_MSR& msr = (UReg_MSR&)MSR;
|
||||||
if (!msr.FP)
|
if (!msr.FP)
|
||||||
{
|
{
|
||||||
PC = NPC = data;
|
|
||||||
PowerPC::ppcState.Exceptions |= EXCEPTION_FPU_UNAVAILABLE;
|
PowerPC::ppcState.Exceptions |= EXCEPTION_FPU_UNAVAILABLE;
|
||||||
PowerPC::CheckExceptions();
|
PowerPC::CheckExceptions();
|
||||||
|
PowerPC::ppcState.downcount -= data;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool CheckDSI(u32 data)
|
||||||
|
{
|
||||||
|
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
|
||||||
|
{
|
||||||
|
PowerPC::CheckExceptions();
|
||||||
|
PowerPC::ppcState.downcount -= data;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -156,22 +173,29 @@ void CachedInterpreter::Jit(u32 address)
|
||||||
|
|
||||||
if (!ops[i].skip)
|
if (!ops[i].skip)
|
||||||
{
|
{
|
||||||
if ((ops[i].opinfo->flags & FL_USE_FPU) && !js.firstFPInstructionFound)
|
bool check_fpu = (ops[i].opinfo->flags & FL_USE_FPU) && !js.firstFPInstructionFound;
|
||||||
|
bool endblock = (ops[i].opinfo->flags & FL_ENDBLOCK) != 0;
|
||||||
|
bool memcheck = (ops[i].opinfo->flags & FL_LOADSTORE) && jo.memcheck;
|
||||||
|
|
||||||
|
if (check_fpu)
|
||||||
{
|
{
|
||||||
m_code.emplace_back(CheckFPU, ops[i].address);
|
m_code.emplace_back(WritePC, ops[i].address);
|
||||||
|
m_code.emplace_back(CheckFPU, js.downcountAmount);
|
||||||
js.firstFPInstructionFound = true;
|
js.firstFPInstructionFound = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ops[i].opinfo->flags & FL_ENDBLOCK)
|
if (endblock || memcheck)
|
||||||
m_code.emplace_back(WritePC, ops[i].address);
|
m_code.emplace_back(WritePC, ops[i].address);
|
||||||
m_code.emplace_back(GetInterpreterOp(ops[i].inst), ops[i].inst);
|
m_code.emplace_back(GetInterpreterOp(ops[i].inst), ops[i].inst);
|
||||||
if (ops[i].opinfo->flags & FL_ENDBLOCK)
|
if (memcheck)
|
||||||
|
m_code.emplace_back(CheckDSI, js.downcountAmount);
|
||||||
|
if (endblock)
|
||||||
m_code.emplace_back(EndBlock, js.downcountAmount);
|
m_code.emplace_back(EndBlock, js.downcountAmount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (code_block.m_broken)
|
if (code_block.m_broken)
|
||||||
{
|
{
|
||||||
m_code.emplace_back(WritePC, nextPC);
|
m_code.emplace_back(WriteBrokenBlockNPC, nextPC);
|
||||||
m_code.emplace_back(EndBlock, js.downcountAmount);
|
m_code.emplace_back(EndBlock, js.downcountAmount);
|
||||||
}
|
}
|
||||||
m_code.emplace_back();
|
m_code.emplace_back();
|
||||||
|
@ -186,6 +210,7 @@ void CachedInterpreter::ClearCache()
|
||||||
{
|
{
|
||||||
m_code.clear();
|
m_code.clear();
|
||||||
JitBaseBlockCache::Clear();
|
JitBaseBlockCache::Clear();
|
||||||
|
UpdateMemoryOptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CachedInterpreter::WriteDestroyBlock(const u8* location, u32 address)
|
void CachedInterpreter::WriteDestroyBlock(const u8* location, u32 address)
|
||||||
|
|
Loading…
Reference in New Issue