diff --git a/src/backend/core/JIT.cpp b/src/backend/core/JIT.cpp index 28e8488c..4689696c 100644 --- a/src/backend/core/JIT.cpp +++ b/src/backend/core/JIT.cpp @@ -130,7 +130,7 @@ int JIT::Step() { 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 block = code.getCurr(); blockCache[upperIndex][lowerIndex] = block; @@ -147,7 +147,7 @@ int JIT::Step() { code.mov(code.rbp, reinterpret_cast(this)); // Load context pointer //cs_insn *insn; - trace("\tMIPS code (guest PC = 0x{:016X}):", blockPC); + info("\tMIPS code (guest PC = 0x{:016X}):", blockPC); while (!instrEndsBlock) { // CheckCompareInterrupt(); paddr = 0; @@ -180,11 +180,10 @@ int JIT::Step() { blockPC = blockNextPC; blockNextPC += 4; + info("{}", Disassembler::GetInstance().DisassembleSimple(paddr, instruction).full); if((instrEndsBlock = InstrEndsBlock(instruction))) continue; - trace("{}", Disassembler::GetInstance().DisassembleSimple(paddr, instruction).full); - /*if(ShouldServiceInterrupt()) { regs.cop0.FireException(ExceptionCode::Interrupt, 0, blockPC); return 1; @@ -243,4 +242,8 @@ int JIT::Step() { return block(); } #endif + +void JIT::DumpBlockCacheToDisk() { + Util::WriteFileBinary(code.getCode(), code.getSize(), "jit.dump"); +} } // namespace n64 diff --git a/src/backend/core/JIT.hpp b/src/backend/core/JIT.hpp index 9776c2f5..08e9e243 100644 --- a/src/backend/core/JIT.hpp +++ b/src/backend/core/JIT.hpp @@ -32,6 +32,8 @@ struct JIT : BaseCPU { blockCache.resize(kUpperSize); } + void DumpBlockCacheToDisk(); + void InvalidateBlock(u32); private: Registers& regs; diff --git a/src/backend/core/jit/decode.cpp b/src/backend/core/jit/decode.cpp index b55acf90..2b147352 100644 --- a/src/backend/core/jit/decode.cpp +++ b/src/backend/core/jit/decode.cpp @@ -270,7 +270,54 @@ void JIT::Emit(const Instruction instr) { lui(instr); break; case Instruction::COP0: - panic("[JIT]: Unimplemented Cop0 decode"); + switch (instr.cop_rs()) { + case 0x00: + code.mov(code.ARG2, instr); + emitMemberFunctionCall(&Cop0::mfc0, ®s.cop0); + break; + case 0x01: + code.mov(code.ARG2, instr); + emitMemberFunctionCall(&Cop0::dmfc0, ®s.cop0); + break; + case 0x04: + code.mov(code.ARG2, instr); + emitMemberFunctionCall(&Cop0::mtc0, ®s.cop0); + break; + case 0x05: + code.mov(code.ARG2, instr); + emitMemberFunctionCall(&Cop0::dmtc0, ®s.cop0); + break; + case 0x10 ... 0x1F: + switch (instr.cop_funct()) { + case 0x01: + emitMemberFunctionCall(&Cop0::tlbr, ®s.cop0); + break; + case 0x02: + code.mov(code.ARG2, COP0_REG_INDEX); + emitMemberFunctionCall(&Cop0::GetReg32, ®s.cop0); + code.mov(code.ARG2, code.rax); + code.and_(code.ARG2, 0x3F); + emitMemberFunctionCall(&Cop0::tlbw, ®s.cop0); + break; + case 0x06: + emitMemberFunctionCall(&Cop0::GetRandom, ®s.cop0); + code.mov(code.ARG2, code.rax); + emitMemberFunctionCall(&Cop0::tlbw, ®s.cop0); + break; + case 0x08: + emitMemberFunctionCall(&Cop0::tlbp, ®s.cop0); + break; + case 0x18: + emitMemberFunctionCall(&Cop0::eret, ®s.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; case Instruction::COP1: { @@ -411,6 +458,7 @@ void JIT::Emit(const Instruction instr) { sd(instr); break; default: + DumpBlockCacheToDisk(); panic("Unimplemented instruction {:02X} ({:08X}) (pc: {:016X})", instr.opcode(), u32(instr), static_cast(regs.oldPC)); } } diff --git a/src/backend/core/jit/instructions.cpp b/src/backend/core/jit/instructions.cpp index 89140f83..78edde2e 100644 --- a/src/backend/core/jit/instructions.cpp +++ b/src/backend/core/jit/instructions.cpp @@ -891,9 +891,7 @@ void JIT::lbu(const Instruction instr) { // regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, regs.oldPC); panic("[JIT]: Unhandled TLBL exception in LBU!"); } else { - code.mov(code.ARG2, - code.ptr[code.rbp + (reinterpret_cast(®s) - reinterpret_cast(this))]); - code.mov(code.ARG3, paddr); + code.mov(code.ARG2, paddr); emitMemberFunctionCall(&Mem::Read, &mem); regs.Write(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); panic("[JIT]: Unhandled TLBL exception in LB (pc: 0x{:016X})!", blockPC); } else { - code.mov(code.ARG2, - code.ptr[code.rbp + (reinterpret_cast(®s) - reinterpret_cast(this))]); - code.mov(code.ARG3, paddr); + code.mov(code.ARG2, paddr); emitMemberFunctionCall(&Mem::Read, &mem); regs.Write(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); panic("[JIT]: Unhandled TLBL exception in LD!"); } else { - code.mov(code.ARG2, - code.ptr[code.rbp + (reinterpret_cast(®s) - reinterpret_cast(this))]); - code.mov(code.ARG3, paddr); + code.mov(code.ARG2, paddr); emitMemberFunctionCall(&Mem::Read, &mem); regs.Write(instr.rt(), code.rax); } @@ -1026,8 +1020,7 @@ void JIT::lh(const Instruction instr) { return; } - code.mov(code.ARG2, code.ptr[code.rbp + (reinterpret_cast(®s) - reinterpret_cast(this))]); - code.mov(code.ARG3, paddr); + code.mov(code.ARG2, paddr); emitMemberFunctionCall(&Mem::Read, &mem); regs.Write(instr.rt(), code.rax); return; @@ -1052,8 +1045,7 @@ void JIT::lhu(const Instruction instr) { return; } - code.mov(code.ARG2, code.ptr[code.rbp + (reinterpret_cast(®s) - reinterpret_cast(this))]); - code.mov(code.ARG3, paddr); + code.mov(code.ARG2, paddr); emitMemberFunctionCall(&Mem::Read, &mem); regs.Write(instr.rt(), code.rax); } @@ -1064,8 +1056,7 @@ void JIT::lhu(const Instruction instr) { code.mov(code.ARG4, reinterpret_cast(&paddr)); emitMemberFunctionCall(&Cop0::MapVAddr, ®s.cop0); - code.mov(code.ARG2, code.ptr[code.rbp + (reinterpret_cast(®s) - reinterpret_cast(this))]); - code.mov(code.ARG3, code.qword[code.ARG4]); + code.mov(code.ARG2, code.qword[code.ARG4]); emitMemberFunctionCall(&Mem::Read, &mem); regs.Write(instr.rt(), code.rax); } @@ -1094,8 +1085,7 @@ void JIT::lw(const Instruction instr) { return; } - code.mov(code.ARG2, code.ptr[code.rbp + (reinterpret_cast(®s) - reinterpret_cast(this))]); - code.mov(code.ARG3, paddr); + code.mov(code.ARG2, paddr); emitMemberFunctionCall(&Mem::Read, &mem); regs.Write(instr.rt(), code.rax); return; @@ -1109,8 +1099,7 @@ void JIT::lw(const Instruction instr) { code.mov(code.ARG4, reinterpret_cast(&paddr)); emitMemberFunctionCall(&Cop0::MapVAddr, ®s.cop0); - code.mov(code.ARG2, code.ptr[code.rbp + (reinterpret_cast(®s) - reinterpret_cast(this))]); - code.mov(code.ARG3, code.qword[code.ARG4]); + code.mov(code.ARG2, code.qword[code.ARG4]); emitMemberFunctionCall(&Mem::Read, &mem); regs.Write(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); panic("[JIT]: Unhandled TLBS exception in SW!"); } else { - code.lea(code.ARG2, - code.ptr[code.rbp + (reinterpret_cast(®s) - reinterpret_cast(this))]); - code.mov(code.ARG3, physical); - regs.Read(instr.rt(), code.ARG4); + code.mov(code.ARG2, physical); + regs.Read(instr.rt(), code.ARG3); emitMemberFunctionCall(&Mem::WriteJIT, &mem); } @@ -1382,10 +1369,8 @@ void JIT::sw(const Instruction instr) { // regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::STORE), 0, regs.oldPC); panic("[JIT]: Unhandled TLBS exception in SW!"); } else { - code.mov(code.ARG2, - code.ptr[code.rbp + (reinterpret_cast(®s) - reinterpret_cast(this))]); - code.mov(code.ARG3, physical); - regs.Read(instr.rt(), code.ARG4); + code.mov(code.ARG2, physical); + regs.Read(instr.rt(), code.ARG3); emitMemberFunctionCall(&Mem::WriteJIT, &mem); } @@ -1402,9 +1387,8 @@ void JIT::sw(const Instruction instr) { code.mov(code.ARG4, reinterpret_cast(&physical)); emitMemberFunctionCall(&Cop0::MapVAddr, ®s.cop0); - code.mov(code.ARG2, code.ptr[code.rbp + (reinterpret_cast(®s) - reinterpret_cast(this))]); - code.mov(code.ARG3, code.qword[code.ARG4]); - regs.Read(instr.rt(), code.ARG4); + code.mov(code.ARG2, code.qword[code.ARG4]); + regs.Read(instr.rt(), code.ARG3); emitMemberFunctionCall(&Mem::WriteJIT, &mem); return; @@ -1419,9 +1403,8 @@ void JIT::sw(const Instruction instr) { code.mov(code.ARG4, reinterpret_cast(&physical)); emitMemberFunctionCall(&Cop0::MapVAddr, ®s.cop0); - code.mov(code.ARG2, code.ptr[code.rbp + (reinterpret_cast(®s) - reinterpret_cast(this))]); - code.mov(code.ARG3, code.qword[code.ARG4]); - regs.Read(instr.rt(), code.ARG4); + code.mov(code.ARG2, code.qword[code.ARG4]); + regs.Read(instr.rt(), code.ARG3); emitMemberFunctionCall(&Mem::WriteJIT, &mem); } diff --git a/src/backend/core/registers/Cop0.hpp b/src/backend/core/registers/Cop0.hpp index 43f228f0..9168aab3 100644 --- a/src/backend/core/registers/Cop0.hpp +++ b/src/backend/core/registers/Cop0.hpp @@ -264,6 +264,8 @@ struct Cop0 { void decode(const Instruction); private: + friend struct JIT; + [[nodiscard]] FORCE_INLINE u32 GetWired() const { return wired & 0x3F; } [[nodiscard]] FORCE_INLINE u32 GetCount() const { return u32(u64(count >> 1)); } diff --git a/src/backend/core/registers/Registers.hpp b/src/backend/core/registers/Registers.hpp index f1a1d3e9..0249407f 100644 --- a/src/backend/core/registers/Registers.hpp +++ b/src/backend/core/registers/Registers.hpp @@ -18,8 +18,8 @@ struct Registers { return regIsConstant & (1 << index); } - [[nodiscard]] bool IsRegConstant(const u32 first, const u32 second) const { - return IsRegConstant(first) && IsRegConstant(second); + [[nodiscard]] bool IsRegConstant(const u32 index1, const u32 index2) const { + return IsRegConstant(index1) && IsRegConstant(index2); } bool GetLOConstant() {