From f5bfce657c90219cebe933978c91f2d1e3d0d1e6 Mon Sep 17 00:00:00 2001 From: EmptyChaos Date: Thu, 8 Sep 2016 06:42:43 +0000 Subject: [PATCH] CachedInterpreter: Fix CoreTiming contract Call CoreTiming::Advance() before executing the slice, not after. --- .../Core/Core/PowerPC/CachedInterpreter.cpp | 66 +++++++++++-------- Source/Core/Core/PowerPC/CachedInterpreter.h | 3 +- 2 files changed, 39 insertions(+), 30 deletions(-) diff --git a/Source/Core/Core/PowerPC/CachedInterpreter.cpp b/Source/Core/Core/PowerPC/CachedInterpreter.cpp index 5a560d9d24..de7aa218ae 100644 --- a/Source/Core/Core/PowerPC/CachedInterpreter.cpp +++ b/Source/Core/Core/PowerPC/CachedInterpreter.cpp @@ -32,49 +32,57 @@ void CachedInterpreter::Shutdown() JitBaseBlockCache::Shutdown(); } +void CachedInterpreter::ExecuteOneBlock() +{ + const u8* normal_entry = JitBaseBlockCache::Dispatch(); + const Instruction* code = reinterpret_cast(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() { - 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() { - const u8* normalEntry = jit->GetBlockCache()->Dispatch(); - const Instruction* code = reinterpret_cast(normalEntry); - - 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; - } - } + // Enter new timing slice + CoreTiming::Advance(); + ExecuteOneBlock(); } static void EndBlock(UGeckoInstruction data) { PC = NPC; PowerPC::ppcState.downcount -= data.hex; - if (PowerPC::ppcState.downcount <= 0) - { - CoreTiming::Advance(); - } } static void WritePC(UGeckoInstruction data) diff --git a/Source/Core/Core/PowerPC/CachedInterpreter.h b/Source/Core/Core/PowerPC/CachedInterpreter.h index f91322eb4d..3b2423e9ee 100644 --- a/Source/Core/Core/PowerPC/CachedInterpreter.h +++ b/Source/Core/Core/PowerPC/CachedInterpreter.h @@ -56,7 +56,8 @@ private: }; const u8* GetCodePtr() { return (u8*)(m_code.data() + m_code.size()); } - std::vector m_code; + void ExecuteOneBlock(); + std::vector m_code; PPCAnalyst::CodeBuffer code_buffer; };