CachedInterpreter: Fix CoreTiming contract
Call CoreTiming::Advance() before executing the slice, not after.
This commit is contained in:
parent
1bcd129683
commit
f5bfce657c
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue