we can emit the instruction inside the delay slot before actually emitting the branch

This commit is contained in:
irisz64
2025-07-08 09:06:49 +02:00
parent d072d37733
commit c51725e42f
2 changed files with 37 additions and 25 deletions

View File

@@ -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<int>(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD)), static_cast<u64>(blockPC));
}
return mem.Read<u32>(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<int>(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD)), static_cast<u64>(blockPC));
}
instruction = mem.Read<u32>(regs, paddr);
if(instrEndsBlock = InstrEndsBlock(instruction))
continue;
/*u32 bswapped = bswap(instruction);
auto count = cs_disasm(disassemblerMips, reinterpret_cast<const u8 *>(&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<u32>(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);