JIT stuff that I do not know how to comment

This commit is contained in:
irisz64
2025-12-18 11:20:56 +01:00
parent 70edba4ced
commit c2d6d5a8a9
6 changed files with 78 additions and 40 deletions

View File

@@ -130,7 +130,7 @@ int JIT::Step() {
blockCache[upperIndex].resize(kLowerSize); blockCache[upperIndex].resize(kLowerSize);
} }
trace("[JIT]: Compiling block @ 0x{:016X}:", blockPC); info("[JIT]: Compiling block @ 0x{:016X}:", blockPC);
const auto blockInfo = code.getCurr(); const auto blockInfo = code.getCurr();
const auto block = code.getCurr<BlockFn>(); const auto block = code.getCurr<BlockFn>();
blockCache[upperIndex][lowerIndex] = block; blockCache[upperIndex][lowerIndex] = block;
@@ -147,7 +147,7 @@ int JIT::Step() {
code.mov(code.rbp, reinterpret_cast<uintptr_t>(this)); // Load context pointer code.mov(code.rbp, reinterpret_cast<uintptr_t>(this)); // Load context pointer
//cs_insn *insn; //cs_insn *insn;
trace("\tMIPS code (guest PC = 0x{:016X}):", blockPC); info("\tMIPS code (guest PC = 0x{:016X}):", blockPC);
while (!instrEndsBlock) { while (!instrEndsBlock) {
// CheckCompareInterrupt(); // CheckCompareInterrupt();
paddr = 0; paddr = 0;
@@ -180,11 +180,10 @@ int JIT::Step() {
blockPC = blockNextPC; blockPC = blockNextPC;
blockNextPC += 4; blockNextPC += 4;
info("{}", Disassembler::GetInstance().DisassembleSimple(paddr, instruction).full);
if((instrEndsBlock = InstrEndsBlock(instruction))) if((instrEndsBlock = InstrEndsBlock(instruction)))
continue; continue;
trace("{}", Disassembler::GetInstance().DisassembleSimple(paddr, instruction).full);
/*if(ShouldServiceInterrupt()) { /*if(ShouldServiceInterrupt()) {
regs.cop0.FireException(ExceptionCode::Interrupt, 0, blockPC); regs.cop0.FireException(ExceptionCode::Interrupt, 0, blockPC);
return 1; return 1;
@@ -243,4 +242,8 @@ int JIT::Step() {
return block(); return block();
} }
#endif #endif
void JIT::DumpBlockCacheToDisk() {
Util::WriteFileBinary(code.getCode<u8*>(), code.getSize(), "jit.dump");
}
} // namespace n64 } // namespace n64

View File

@@ -32,6 +32,8 @@ struct JIT : BaseCPU {
blockCache.resize(kUpperSize); blockCache.resize(kUpperSize);
} }
void DumpBlockCacheToDisk();
void InvalidateBlock(u32); void InvalidateBlock(u32);
private: private:
Registers& regs; Registers& regs;

View File

@@ -270,7 +270,54 @@ void JIT::Emit(const Instruction instr) {
lui(instr); lui(instr);
break; break;
case Instruction::COP0: case Instruction::COP0:
panic("[JIT]: Unimplemented Cop0 decode"); switch (instr.cop_rs()) {
case 0x00:
code.mov(code.ARG2, instr);
emitMemberFunctionCall(&Cop0::mfc0, &regs.cop0);
break;
case 0x01:
code.mov(code.ARG2, instr);
emitMemberFunctionCall(&Cop0::dmfc0, &regs.cop0);
break;
case 0x04:
code.mov(code.ARG2, instr);
emitMemberFunctionCall(&Cop0::mtc0, &regs.cop0);
break;
case 0x05:
code.mov(code.ARG2, instr);
emitMemberFunctionCall(&Cop0::dmtc0, &regs.cop0);
break;
case 0x10 ... 0x1F:
switch (instr.cop_funct()) {
case 0x01:
emitMemberFunctionCall(&Cop0::tlbr, &regs.cop0);
break;
case 0x02:
code.mov(code.ARG2, COP0_REG_INDEX);
emitMemberFunctionCall(&Cop0::GetReg32, &regs.cop0);
code.mov(code.ARG2, code.rax);
code.and_(code.ARG2, 0x3F);
emitMemberFunctionCall(&Cop0::tlbw, &regs.cop0);
break;
case 0x06:
emitMemberFunctionCall(&Cop0::GetRandom, &regs.cop0);
code.mov(code.ARG2, code.rax);
emitMemberFunctionCall(&Cop0::tlbw, &regs.cop0);
break;
case 0x08:
emitMemberFunctionCall(&Cop0::tlbp, &regs.cop0);
break;
case 0x18:
emitMemberFunctionCall(&Cop0::eret, &regs.cop0);
break;
default:
panic("Unimplemented COP0 function {} ({:08X}) ({:016X})", instr.cop_funct(), u32(instr),
regs.oldPC);
}
break;
default:
panic("Unimplemented COP0 instruction {}", instr.cop_rs());
}
break; break;
case Instruction::COP1: case Instruction::COP1:
{ {
@@ -411,6 +458,7 @@ void JIT::Emit(const Instruction instr) {
sd(instr); sd(instr);
break; break;
default: default:
DumpBlockCacheToDisk();
panic("Unimplemented instruction {:02X} ({:08X}) (pc: {:016X})", instr.opcode(), u32(instr), static_cast<u64>(regs.oldPC)); panic("Unimplemented instruction {:02X} ({:08X}) (pc: {:016X})", instr.opcode(), u32(instr), static_cast<u64>(regs.oldPC));
} }
} }

View File

@@ -891,9 +891,7 @@ void JIT::lbu(const Instruction instr) {
// regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); // regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC);
panic("[JIT]: Unhandled TLBL exception in LBU!"); panic("[JIT]: Unhandled TLBL exception in LBU!");
} else { } else {
code.mov(code.ARG2, code.mov(code.ARG2, paddr);
code.ptr[code.rbp + (reinterpret_cast<uintptr_t>(&regs) - reinterpret_cast<uintptr_t>(this))]);
code.mov(code.ARG3, paddr);
emitMemberFunctionCall(&Mem::Read<u8>, &mem); emitMemberFunctionCall(&Mem::Read<u8>, &mem);
regs.Write<u8>(instr.rt(), code.rax); regs.Write<u8>(instr.rt(), code.rax);
} }
@@ -910,9 +908,7 @@ void JIT::lb(const Instruction instr) {
// regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); // regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC);
panic("[JIT]: Unhandled TLBL exception in LB (pc: 0x{:016X})!", blockPC); panic("[JIT]: Unhandled TLBL exception in LB (pc: 0x{:016X})!", blockPC);
} else { } else {
code.mov(code.ARG2, code.mov(code.ARG2, paddr);
code.ptr[code.rbp + (reinterpret_cast<uintptr_t>(&regs) - reinterpret_cast<uintptr_t>(this))]);
code.mov(code.ARG3, paddr);
emitMemberFunctionCall(&Mem::Read<u8>, &mem); emitMemberFunctionCall(&Mem::Read<u8>, &mem);
regs.Write<s8>(instr.rt(), code.rax); regs.Write<s8>(instr.rt(), code.rax);
} }
@@ -937,9 +933,7 @@ void JIT::ld(const Instruction instr) {
// regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); // regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC);
panic("[JIT]: Unhandled TLBL exception in LD!"); panic("[JIT]: Unhandled TLBL exception in LD!");
} else { } else {
code.mov(code.ARG2, code.mov(code.ARG2, paddr);
code.ptr[code.rbp + (reinterpret_cast<uintptr_t>(&regs) - reinterpret_cast<uintptr_t>(this))]);
code.mov(code.ARG3, paddr);
emitMemberFunctionCall(&Mem::Read<u64>, &mem); emitMemberFunctionCall(&Mem::Read<u64>, &mem);
regs.Write<u64>(instr.rt(), code.rax); regs.Write<u64>(instr.rt(), code.rax);
} }
@@ -1026,8 +1020,7 @@ void JIT::lh(const Instruction instr) {
return; return;
} }
code.mov(code.ARG2, code.ptr[code.rbp + (reinterpret_cast<uintptr_t>(&regs) - reinterpret_cast<uintptr_t>(this))]); code.mov(code.ARG2, paddr);
code.mov(code.ARG3, paddr);
emitMemberFunctionCall(&Mem::Read<u16>, &mem); emitMemberFunctionCall(&Mem::Read<u16>, &mem);
regs.Write<s16>(instr.rt(), code.rax); regs.Write<s16>(instr.rt(), code.rax);
return; return;
@@ -1052,8 +1045,7 @@ void JIT::lhu(const Instruction instr) {
return; return;
} }
code.mov(code.ARG2, code.ptr[code.rbp + (reinterpret_cast<uintptr_t>(&regs) - reinterpret_cast<uintptr_t>(this))]); code.mov(code.ARG2, paddr);
code.mov(code.ARG3, paddr);
emitMemberFunctionCall(&Mem::Read<u16>, &mem); emitMemberFunctionCall(&Mem::Read<u16>, &mem);
regs.Write<u16>(instr.rt(), code.rax); regs.Write<u16>(instr.rt(), code.rax);
} }
@@ -1064,8 +1056,7 @@ void JIT::lhu(const Instruction instr) {
code.mov(code.ARG4, reinterpret_cast<uintptr_t>(&paddr)); code.mov(code.ARG4, reinterpret_cast<uintptr_t>(&paddr));
emitMemberFunctionCall(&Cop0::MapVAddr, &regs.cop0); emitMemberFunctionCall(&Cop0::MapVAddr, &regs.cop0);
code.mov(code.ARG2, code.ptr[code.rbp + (reinterpret_cast<uintptr_t>(&regs) - reinterpret_cast<uintptr_t>(this))]); code.mov(code.ARG2, code.qword[code.ARG4]);
code.mov(code.ARG3, code.qword[code.ARG4]);
emitMemberFunctionCall(&Mem::Read<u16>, &mem); emitMemberFunctionCall(&Mem::Read<u16>, &mem);
regs.Write<u16>(instr.rt(), code.rax); regs.Write<u16>(instr.rt(), code.rax);
} }
@@ -1094,8 +1085,7 @@ void JIT::lw(const Instruction instr) {
return; return;
} }
code.mov(code.ARG2, code.ptr[code.rbp + (reinterpret_cast<uintptr_t>(&regs) - reinterpret_cast<uintptr_t>(this))]); code.mov(code.ARG2, paddr);
code.mov(code.ARG3, paddr);
emitMemberFunctionCall(&Mem::Read<u32>, &mem); emitMemberFunctionCall(&Mem::Read<u32>, &mem);
regs.Write<s32>(instr.rt(), code.rax); regs.Write<s32>(instr.rt(), code.rax);
return; return;
@@ -1109,8 +1099,7 @@ void JIT::lw(const Instruction instr) {
code.mov(code.ARG4, reinterpret_cast<uintptr_t>(&paddr)); code.mov(code.ARG4, reinterpret_cast<uintptr_t>(&paddr));
emitMemberFunctionCall(&Cop0::MapVAddr, &regs.cop0); emitMemberFunctionCall(&Cop0::MapVAddr, &regs.cop0);
code.mov(code.ARG2, code.ptr[code.rbp + (reinterpret_cast<uintptr_t>(&regs) - reinterpret_cast<uintptr_t>(this))]); code.mov(code.ARG2, code.qword[code.ARG4]);
code.mov(code.ARG3, code.qword[code.ARG4]);
emitMemberFunctionCall(&Mem::Read<u32>, &mem); emitMemberFunctionCall(&Mem::Read<u32>, &mem);
regs.Write<s32>(instr.rt(), code.rax); regs.Write<s32>(instr.rt(), code.rax);
} }
@@ -1357,10 +1346,8 @@ void JIT::sw(const Instruction instr) {
// regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); // regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC);
panic("[JIT]: Unhandled TLBS exception in SW!"); panic("[JIT]: Unhandled TLBS exception in SW!");
} else { } else {
code.lea(code.ARG2, code.mov(code.ARG2, physical);
code.ptr[code.rbp + (reinterpret_cast<uintptr_t>(&regs) - reinterpret_cast<uintptr_t>(this))]); regs.Read<s64>(instr.rt(), code.ARG3);
code.mov(code.ARG3, physical);
regs.Read<s64>(instr.rt(), code.ARG4);
emitMemberFunctionCall(&Mem::WriteJIT<u32>, &mem); emitMemberFunctionCall(&Mem::WriteJIT<u32>, &mem);
} }
@@ -1382,10 +1369,8 @@ void JIT::sw(const Instruction instr) {
// regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); // regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC);
panic("[JIT]: Unhandled TLBS exception in SW!"); panic("[JIT]: Unhandled TLBS exception in SW!");
} else { } else {
code.mov(code.ARG2, code.mov(code.ARG2, physical);
code.ptr[code.rbp + (reinterpret_cast<uintptr_t>(&regs) - reinterpret_cast<uintptr_t>(this))]); regs.Read<s64>(instr.rt(), code.ARG3);
code.mov(code.ARG3, physical);
regs.Read<s64>(instr.rt(), code.ARG4);
emitMemberFunctionCall(&Mem::WriteJIT<u32>, &mem); emitMemberFunctionCall(&Mem::WriteJIT<u32>, &mem);
} }
@@ -1402,9 +1387,8 @@ void JIT::sw(const Instruction instr) {
code.mov(code.ARG4, reinterpret_cast<uintptr_t>(&physical)); code.mov(code.ARG4, reinterpret_cast<uintptr_t>(&physical));
emitMemberFunctionCall(&Cop0::MapVAddr, &regs.cop0); emitMemberFunctionCall(&Cop0::MapVAddr, &regs.cop0);
code.mov(code.ARG2, code.ptr[code.rbp + (reinterpret_cast<uintptr_t>(&regs) - reinterpret_cast<uintptr_t>(this))]); code.mov(code.ARG2, code.qword[code.ARG4]);
code.mov(code.ARG3, code.qword[code.ARG4]); regs.Read<s64>(instr.rt(), code.ARG3);
regs.Read<s64>(instr.rt(), code.ARG4);
emitMemberFunctionCall(&Mem::WriteJIT<u32>, &mem); emitMemberFunctionCall(&Mem::WriteJIT<u32>, &mem);
return; return;
@@ -1419,9 +1403,8 @@ void JIT::sw(const Instruction instr) {
code.mov(code.ARG4, reinterpret_cast<uintptr_t>(&physical)); code.mov(code.ARG4, reinterpret_cast<uintptr_t>(&physical));
emitMemberFunctionCall(&Cop0::MapVAddr, &regs.cop0); emitMemberFunctionCall(&Cop0::MapVAddr, &regs.cop0);
code.mov(code.ARG2, code.ptr[code.rbp + (reinterpret_cast<uintptr_t>(&regs) - reinterpret_cast<uintptr_t>(this))]); code.mov(code.ARG2, code.qword[code.ARG4]);
code.mov(code.ARG3, code.qword[code.ARG4]); regs.Read<s64>(instr.rt(), code.ARG3);
regs.Read<s64>(instr.rt(), code.ARG4);
emitMemberFunctionCall(&Mem::WriteJIT<u32>, &mem); emitMemberFunctionCall(&Mem::WriteJIT<u32>, &mem);
} }

View File

@@ -264,6 +264,8 @@ struct Cop0 {
void decode(const Instruction); void decode(const Instruction);
private: private:
friend struct JIT;
[[nodiscard]] FORCE_INLINE u32 GetWired() const { return wired & 0x3F; } [[nodiscard]] FORCE_INLINE u32 GetWired() const { return wired & 0x3F; }
[[nodiscard]] FORCE_INLINE u32 GetCount() const { return u32(u64(count >> 1)); } [[nodiscard]] FORCE_INLINE u32 GetCount() const { return u32(u64(count >> 1)); }

View File

@@ -18,8 +18,8 @@ struct Registers {
return regIsConstant & (1 << index); return regIsConstant & (1 << index);
} }
[[nodiscard]] bool IsRegConstant(const u32 first, const u32 second) const { [[nodiscard]] bool IsRegConstant(const u32 index1, const u32 index2) const {
return IsRegConstant(first) && IsRegConstant(second); return IsRegConstant(index1) && IsRegConstant(index2);
} }
bool GetLOConstant() { bool GetLOConstant() {