diff --git a/src/core/CPU/cpu_dynarmic.cpp b/src/core/CPU/cpu_dynarmic.cpp index 85dc70d96..db02904ae 100644 --- a/src/core/CPU/cpu_dynarmic.cpp +++ b/src/core/CPU/cpu_dynarmic.cpp @@ -1,58 +1,51 @@ #ifdef CPU_DYNARMIC #include "cpu_dynarmic.hpp" - #include "arm_defs.hpp" #include "emulator.hpp" -CPU::CPU(Memory& mem, Kernel& kernel, Emulator& emu) : mem(mem), emu(emu), scheduler(emu.getScheduler()), env(mem, kernel, emu.getScheduler()) { - cp15 = std::make_shared(); +CPU::CPU(Memory& mem, Kernel& kernel, Emulator& emu) + : mem(mem), emu(emu), scheduler(emu.getScheduler()), env(mem, kernel, scheduler) { + cp15 = std::make_shared(); - Dynarmic::A32::UserConfig config; - config.arch_version = Dynarmic::A32::ArchVersion::v6K; - config.callbacks = &env; - config.coprocessors[15] = cp15; - config.define_unpredictable_behaviour = true; - config.global_monitor = &exclusiveMonitor; - config.processor_id = 0; + Dynarmic::A32::UserConfig config; + config.arch_version = Dynarmic::A32::ArchVersion::v6K; + config.callbacks = &env; + config.coprocessors[15] = cp15; + config.define_unpredictable_behaviour = true; + config.global_monitor = &exclusiveMonitor; + config.processor_id = 0; - jit = std::make_unique(config); + jit = std::make_unique(config); } void CPU::reset() { - setCPSR(CPSR::UserMode); - setFPSCR(FPSCR::MainThreadDefault); - - cp15->reset(); - cp15->setTLSBase(VirtualAddrs::TLSBase); // Set cp15 TLS pointer to the main thread's thread-local storage - jit->Reset(); - jit->ClearCache(); - jit->Regs().fill(0); - jit->ExtRegs().fill(0); + setCPSR(CPSR::UserMode); + setFPSCR(FPSCR::MainThreadDefault); + + cp15->reset(); + cp15->setTLSBase(VirtualAddrs::TLSBase); + jit->Reset(); + jit->ClearCache(); + jit->Regs().fill(0); + jit->ExtRegs().fill(0); } void CPU::runFrame() { - emu.frameDone = false; - - while (!emu.frameDone) { - // Run CPU until the next scheduler event - env.ticksLeft = scheduler.nextTimestamp - scheduler.currentTimestamp; - - execute: - const auto exitReason = jit->Run(); - - // Handle any scheduler events that need handling. - emu.pollScheduler(); - - if (static_cast(exitReason) != 0) [[unlikely]] { - // Cache invalidation needs to exit the JIT so it returns a CacheInvalidation HaltReason. In our case, we just go back to executing - // The goto might be terrible but it does guarantee that this does not recursively call run and crash, instead getting optimized to a jump - if (Dynarmic::Has(exitReason, Dynarmic::HaltReason::CacheInvalidation)) { - goto execute; - } else { - Helpers::panic("Exit reason: %d\nPC: %08X", static_cast(exitReason), getReg(15)); - } - } - } + bool frameDone = false; + while (!frameDone) { + env.ticksLeft = scheduler.nextTimestamp - scheduler.currentTimestamp; + const auto exitReason = jit->Run(); + emu.pollScheduler(); + + if (static_cast(exitReason) != 0) { + if (Dynarmic::Has(exitReason, Dynarmic::HaltReason::CacheInvalidation)) { + continue; // Retry execution + } else { + Helpers::panic("Exit reason: %d\nPC: %08X", static_cast(exitReason), getReg(15)); + } + } + frameDone = emu.frameDone; + } } -#endif // CPU_DYNARMIC \ No newline at end of file +#endif