From 009dd1458d2d9f4907f939885b8bf2a6004a3f58 Mon Sep 17 00:00:00 2001 From: SimoneN64 Date: Tue, 28 Jan 2025 00:12:01 +0100 Subject: [PATCH] [JIT]: Stupid mov bug + start debugging with capstone --- src/backend/core/JIT.cpp | 45 +++++++++++++++++++++--- src/backend/core/JIT.hpp | 2 ++ src/backend/core/jit/instructions.cpp | 6 ++-- src/backend/core/registers/Registers.cpp | 9 +++-- src/frontend/CMakeLists.txt | 5 +-- 5 files changed, 54 insertions(+), 13 deletions(-) diff --git a/src/backend/core/JIT.cpp b/src/backend/core/JIT.cpp index ec935a85..c07a7070 100644 --- a/src/backend/core/JIT.cpp +++ b/src/backend/core/JIT.cpp @@ -2,7 +2,17 @@ #include namespace n64 { -JIT::JIT(ParallelRDP ¶llel) : regs(this), mem(regs, parallel, this) { blockCache.resize(kUpperSize); } +JIT::JIT(ParallelRDP ¶llel) : regs(this), mem(regs, parallel, this) { + blockCache.resize(kUpperSize); + if (cs_open(CS_ARCH_MIPS, static_cast(CS_MODE_MIPS64 | CS_MODE_BIG_ENDIAN), &disassemblerMips) != + CS_ERR_OK) { + Util::panic("Failed to initialize MIPS disassembler"); + } + + if (cs_open(CS_ARCH_X86, static_cast(CS_MODE_64 | CS_MODE_LITTLE_ENDIAN), &disassemblerX86) != CS_ERR_OK) { + Util::panic("Failed to initialize x86 disassembler"); + } +} bool JIT::ShouldServiceInterrupt() const { const bool interrupts_pending = (regs.cop0.status.im & regs.cop0.cause.interruptPending) != 0; @@ -24,7 +34,7 @@ void JIT::CheckCompareInterrupt() { void JIT::InvalidateBlock(const u32 paddr) { if (const u32 index = paddr >> kUpperShift; !blockCache[index].empty()) - blockCache[index].erase(blockCache[index].begin(), blockCache[index].end()); + blockCache[index] = {}; } int JIT::Step() { @@ -44,14 +54,15 @@ int JIT::Step() { if (!blockCache[upperIndex].empty()) { if (blockCache[upperIndex][lowerIndex]) { - Util::trace("[JIT]: Executing already compiled block @ 0x{:016X}", blockPC); + // Util::trace("[JIT]: Executing already compiled block @ 0x{:016X}", blockPC); return blockCache[upperIndex][lowerIndex](); } } else { blockCache[upperIndex].resize(kLowerSize); } - Util::trace("[JIT]: Compiling block @ 0x{:016X}", blockPC); + Util::trace("[JIT]: Compiling block @ 0x{:016X}:", blockPC); + // const auto blockInfo = code.getCurr(); const auto block = code.getCurr(); blockCache[upperIndex][lowerIndex] = block; @@ -68,6 +79,8 @@ int JIT::Step() { code.push(code.rbp); code.mov(code.rbp, reinterpret_cast(this)); // Load context pointer + // cs_insn *insn; + Util::trace("\tMIPS code (guest PC = 0x{:016X}):", blockPC); while (!instrInDelaySlot) { // CheckCompareInterrupt(); @@ -90,7 +103,17 @@ int JIT::Step() { const u32 instruction = mem.Read(regs, paddr); - /*if(ShouldServiceInterrupt()) { + /*u32 bswapped = bswap(instruction); + auto count = cs_disasm(disassemblerMips, reinterpret_cast(&bswapped), 4, blockPC, 0, &insn); + + if (count > 0) { + Util::trace("\t\t0x{:016X}:\t{}\t\t{}\n", insn->address, insn->mnemonic, insn->op_str); + cs_free(insn, count); + } else { + Util::trace("\t\tCould not disassemble 0x{:08X} due to error {}\n", instruction, (int)cs_errno(disassemblerMips)); + } + + if(ShouldServiceInterrupt()) { regs.cop0.FireException(ExceptionCode::Interrupt, 0, blockPC); return 1; }*/ @@ -127,6 +150,18 @@ int JIT::Step() { code.add(code.rsp, 8); code.ret(); code.setProtectModeRE(); + /* static auto blockInfoSize = 0; + blockInfoSize = code.getSize() - blockInfoSize; + + Util::trace("\tX86 code (block address = 0x{:016X}):", (uintptr_t)block); + auto count = cs_disasm(disassemblerX86, blockInfo, blockInfoSize, (uintptr_t)block, 0, &insn); + if (count > 0) { + for (size_t j = 0; j < count; j++) { + Util::trace("\t\t0x{:016X}:\t{}\t\t{}\n", insn[j].address, insn[j].mnemonic, insn[j].op_str); + } + + cs_free(insn, count); + }*/ // const auto dump = code.getCode(); // Util::WriteFileBinary(dump, code.getSize(), "jit.dump"); // Util::panic(""); diff --git a/src/backend/core/JIT.hpp b/src/backend/core/JIT.hpp index 4462dee5..07dbd566 100644 --- a/src/backend/core/JIT.hpp +++ b/src/backend/core/JIT.hpp @@ -4,6 +4,7 @@ #include #include #include +#include namespace n64 { struct Core; @@ -46,6 +47,7 @@ private: using BlockFn = int (*)(); std::vector> blockCache; Xbyak::Label branch_likely_not_taken; + csh disassemblerMips, disassemblerX86; template Xbyak::Address GPR(const size_t index) const { diff --git a/src/backend/core/jit/instructions.cpp b/src/backend/core/jit/instructions.cpp index 323b94b6..d15ba471 100644 --- a/src/backend/core/jit/instructions.cpp +++ b/src/backend/core/jit/instructions.cpp @@ -166,7 +166,7 @@ void JIT::BranchTaken(const s64 offs) { } void JIT::BranchNotTaken() { - code.mov(code.rax, blockPC); + code.mov(code.rax, blockPC + 4); code.mov(REG(qword, pc), code.rax); } @@ -1241,9 +1241,9 @@ void JIT::sltu(u32 instr) { } void JIT::sll(u32 instr) { - u8 sa = ((instr >> 6) & 0x1f); + const u8 sa = ((instr >> 6) & 0x1f); if (regs.IsRegConstant(RT(instr))) { - s32 result = regs.Read(RT(instr)) << sa; + const s32 result = regs.Read(RT(instr)) << sa; regs.Write(RD(instr), (s64)result); } else { regs.Read(RT(instr), code.rax); diff --git a/src/backend/core/registers/Registers.cpp b/src/backend/core/registers/Registers.cpp index 5355bd17..f9af5387 100644 --- a/src/backend/core/registers/Registers.cpp +++ b/src/backend/core/registers/Registers.cpp @@ -219,7 +219,8 @@ void Registers::Write(size_t idx, Xbyak::Reg v) { if (!jit) Util::panic("Did you try to call Registers::Write(size_t, *Xbyak::Reg*) from the interpreter?"); - jit->code.mov(jit->GPR(idx), v.cvt8()); + jit->code.movzx(v.cvt64(), v.cvt8()); + jit->code.mov(jit->GPR(idx), v.cvt64()); } template <> @@ -246,7 +247,8 @@ void Registers::Write(size_t idx, Xbyak::Reg v) { if (!jit) Util::panic("Did you try to call Registers::Write(size_t, *Xbyak::Reg*) from the interpreter?"); - jit->code.mov(jit->GPR(idx), v.cvt16()); + jit->code.movzx(v.cvt64(), v.cvt16()); + jit->code.mov(jit->GPR(idx), v.cvt64()); } template <> @@ -273,7 +275,8 @@ void Registers::Write(size_t idx, Xbyak::Reg v) { if (!jit) Util::panic("Did you try to call Registers::Write(size_t, *Xbyak::Reg*) from the interpreter?"); - jit->code.mov(jit->GPR(idx), v.cvt32()); + jit->code.movzx(v.cvt64(), v.cvt32()); + jit->code.mov(jit->GPR(idx), v.cvt64()); } template <> diff --git a/src/frontend/CMakeLists.txt b/src/frontend/CMakeLists.txt index a731a71d..5b114e3e 100644 --- a/src/frontend/CMakeLists.txt +++ b/src/frontend/CMakeLists.txt @@ -65,8 +65,9 @@ add_subdirectory(../backend backend) add_subdirectory(../../external/parallel-rdp parallel-rdp) add_subdirectory(../../external/unarr unarr) add_subdirectory(../../external/SDL SDL) -option(CAPSTONE_ARCHITECTURE_DEFAULT OFF) -option(CAPSTONE_MIPS_SUPPORT ON) +set(CAPSTONE_ARCHITECTURE_DEFAULT OFF) +set(CAPSTONE_MIPS_SUPPORT ON) +set(CAPSTONE_X86_SUPPORT ON) add_subdirectory(../../external/capstone capstone) set(CMAKE_AUTOMOC ON)