diff --git a/src/backend/core/JIT.cpp b/src/backend/core/JIT.cpp index 5b4b7131..3f796669 100644 --- a/src/backend/core/JIT.cpp +++ b/src/backend/core/JIT.cpp @@ -38,6 +38,29 @@ void JIT::InvalidateBlock(const u32 paddr) { blockCache[index] = {}; } +u32 JIT::FetchInstruction() { + u32 paddr = 0; + + if (check_address_error(0b11, u64(blockPC))) [[unlikely]] { + /*regs.cop0.HandleTLBException(blockPC); + regs.cop0.FireException(ExceptionCode::AddressErrorLoad, 0, blockPC); + return 1;*/ + + Util::panic("[JIT]: Unhandled exception ADL due to unaligned PC virtual value! (0x{:016X})", blockPC); + } + + if (!regs.cop0.MapVAddr(Cop0::LOAD, blockPC, paddr)) { + /*regs.cop0.HandleTLBException(blockPC); + regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, blockPC); + return 1;*/ + Util::panic( + "[JIT]: Unhandled exception TLB exception {} when retrieving PC physical address! (virtual: 0x{:016X})", + static_cast(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD)), static_cast(blockPC)); + } + + return mem.Read(regs, paddr); +} + int JIT::Step() { blockOldPC = regs.oldPC; blockPC = regs.pc; @@ -85,24 +108,15 @@ int JIT::Step() { while (!instrEndsBlock) { // CheckCompareInterrupt(); - if (check_address_error(0b11, u64(blockPC))) [[unlikely]] { - /*regs.cop0.HandleTLBException(blockPC); - regs.cop0.FireException(ExceptionCode::AddressErrorLoad, 0, blockPC); - return 1;*/ + instruction = FetchInstruction(); + instructionsInBlock++; - Util::panic("[JIT]: Unhandled exception ADL due to unaligned PC virtual value! (0x{:016X})", blockPC); - } + blockOldPC = blockPC; + blockPC = blockNextPC; + blockNextPC += 4; - if (!regs.cop0.MapVAddr(Cop0::LOAD, blockPC, paddr)) { - /*regs.cop0.HandleTLBException(blockPC); - regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, blockPC); - return 1;*/ - Util::panic( - "[JIT]: Unhandled exception TLB exception {} when retrieving PC physical address! (virtual: 0x{:016X})", - static_cast(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD)), static_cast(blockPC)); - } - - instruction = mem.Read(regs, paddr); + if(instrEndsBlock = InstrEndsBlock(instruction)) + continue; /*u32 bswapped = bswap(instruction); auto count = cs_disasm(disassemblerMips, reinterpret_cast(&bswapped), 4, blockPC, 0, &insn); @@ -119,24 +133,21 @@ int JIT::Step() { return 1; }*/ - blockOldPC = blockPC; - blockPC = blockNextPC; - blockNextPC += 4; - instructionsInBlock++; Emit(instruction); - - instrEndsBlock = InstrEndsBlock(instruction); } - instruction = mem.Read(regs, paddr); - instrEndsBlock = InstrEndsBlock(instruction); + instructionsInBlock++; + const u32 delay_instruction = FetchInstruction(); + instrEndsBlock = InstrEndsBlock(delay_instruction); if(instrEndsBlock) Util::panic("Branch in delay slot - YOU SHOULD KILL YOURSELF, NOW!!!"); blockOldPC = blockPC; blockPC = blockNextPC; blockNextPC += 4; - instructionsInBlock++; + + Emit(delay_instruction); + Emit(instruction); code.mov(code.rax, instructionsInBlock); diff --git a/src/backend/core/JIT.hpp b/src/backend/core/JIT.hpp index 5f96ff28..73f8985e 100644 --- a/src/backend/core/JIT.hpp +++ b/src/backend/core/JIT.hpp @@ -128,6 +128,7 @@ private: void CheckCompareInterrupt() override; std::vector Serialize() override; void Deserialize(const std::vector &) override; + u32 FetchInstruction(); void Emit(u32); void special(u32);