[JIT]: Stupid mov bug + start debugging with capstone

This commit is contained in:
SimoneN64
2025-01-28 00:12:01 +01:00
parent d4ad92a67d
commit 009dd1458d
5 changed files with 54 additions and 13 deletions

View File

@@ -2,7 +2,17 @@
#include <jit/helpers.hpp>
namespace n64 {
JIT::JIT(ParallelRDP &parallel) : regs(this), mem(regs, parallel, this) { blockCache.resize(kUpperSize); }
JIT::JIT(ParallelRDP &parallel) : regs(this), mem(regs, parallel, this) {
blockCache.resize(kUpperSize);
if (cs_open(CS_ARCH_MIPS, static_cast<cs_mode>(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>(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<BlockFn>();
blockCache[upperIndex][lowerIndex] = block;
@@ -68,6 +79,8 @@ int JIT::Step() {
code.push(code.rbp);
code.mov(code.rbp, reinterpret_cast<uintptr_t>(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<u32>(regs, paddr);
/*if(ShouldServiceInterrupt()) {
/*u32 bswapped = bswap(instruction);
auto count = cs_disasm(disassemblerMips, reinterpret_cast<const u8 *>(&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("");

View File

@@ -4,6 +4,7 @@
#include <vector>
#include <xbyak.h>
#include <jit/helpers.hpp>
#include <capstone/capstone.h>
namespace n64 {
struct Core;
@@ -46,6 +47,7 @@ private:
using BlockFn = int (*)();
std::vector<std::vector<BlockFn>> blockCache;
Xbyak::Label branch_likely_not_taken;
csh disassemblerMips, disassemblerX86;
template <typename T>
Xbyak::Address GPR(const size_t index) const {

View File

@@ -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<s64>(RT(instr)) << sa;
const s32 result = regs.Read<s64>(RT(instr)) << sa;
regs.Write(RD(instr), (s64)result);
} else {
regs.Read<s64>(RT(instr), code.rax);

View File

@@ -219,7 +219,8 @@ void Registers::Write<u8>(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<u8>(idx), v.cvt8());
jit->code.movzx(v.cvt64(), v.cvt8());
jit->code.mov(jit->GPR<u64>(idx), v.cvt64());
}
template <>
@@ -246,7 +247,8 @@ void Registers::Write<u16>(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<u16>(idx), v.cvt16());
jit->code.movzx(v.cvt64(), v.cvt16());
jit->code.mov(jit->GPR<u64>(idx), v.cvt64());
}
template <>
@@ -273,7 +275,8 @@ void Registers::Write<u32>(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<u32>(idx), v.cvt32());
jit->code.movzx(v.cvt64(), v.cvt32());
jit->code.mov(jit->GPR<u64>(idx), v.cvt64());
}
template <>