CachedInterpreter: Fix CoreTiming contract

Call CoreTiming::Advance() before executing the slice, not after.
This commit is contained in:
EmptyChaos 2016-09-08 06:42:43 +00:00
parent 1bcd129683
commit f5bfce657c
2 changed files with 39 additions and 30 deletions

View File

@ -32,49 +32,57 @@ void CachedInterpreter::Shutdown()
JitBaseBlockCache::Shutdown(); JitBaseBlockCache::Shutdown();
} }
void CachedInterpreter::ExecuteOneBlock()
{
const u8* normal_entry = JitBaseBlockCache::Dispatch();
const Instruction* code = reinterpret_cast<const Instruction*>(normal_entry);
for (; code->type != Instruction::INSTRUCTION_ABORT; ++code)
{
switch (code->type)
{
case Instruction::INSTRUCTION_TYPE_COMMON:
code->common_callback(UGeckoInstruction(code->data));
break;
case Instruction::INSTRUCTION_TYPE_CONDITIONAL:
if (code->conditional_callback(code->data))
return;
break;
default:
ERROR_LOG(POWERPC, "Unknown CachedInterpreter Instruction: %d", code->type);
break;
}
}
}
void CachedInterpreter::Run() void CachedInterpreter::Run()
{ {
while (!CPU::GetState()) while (CPU::GetState() == CPU::CPU_RUNNING)
{ {
SingleStep(); // Start new timing slice
// NOTE: Exceptions may change PC
CoreTiming::Advance();
do
{
ExecuteOneBlock();
} while (PowerPC::ppcState.downcount > 0);
} }
} }
void CachedInterpreter::SingleStep() void CachedInterpreter::SingleStep()
{ {
const u8* normalEntry = jit->GetBlockCache()->Dispatch(); // Enter new timing slice
const Instruction* code = reinterpret_cast<const Instruction*>(normalEntry); CoreTiming::Advance();
ExecuteOneBlock();
while (true)
{
switch (code->type)
{
case Instruction::INSTRUCTION_ABORT:
return;
case Instruction::INSTRUCTION_TYPE_COMMON:
code->common_callback(UGeckoInstruction(code->data));
code++;
break;
case Instruction::INSTRUCTION_TYPE_CONDITIONAL:
bool ret = code->conditional_callback(code->data);
code++;
if (ret)
return;
break;
}
}
} }
static void EndBlock(UGeckoInstruction data) static void EndBlock(UGeckoInstruction data)
{ {
PC = NPC; PC = NPC;
PowerPC::ppcState.downcount -= data.hex; PowerPC::ppcState.downcount -= data.hex;
if (PowerPC::ppcState.downcount <= 0)
{
CoreTiming::Advance();
}
} }
static void WritePC(UGeckoInstruction data) static void WritePC(UGeckoInstruction data)

View File

@ -56,7 +56,8 @@ private:
}; };
const u8* GetCodePtr() { return (u8*)(m_code.data() + m_code.size()); } const u8* GetCodePtr() { return (u8*)(m_code.data() + m_code.size()); }
std::vector<Instruction> m_code; void ExecuteOneBlock();
std::vector<Instruction> m_code;
PPCAnalyst::CodeBuffer code_buffer; PPCAnalyst::CodeBuffer code_buffer;
}; };