From 219c46e475b2a72537c1caf39d4ef3324fa01b75 Mon Sep 17 00:00:00 2001 From: IrisZ64 Date: Thu, 18 Dec 2025 21:36:45 +0100 Subject: [PATCH] fix jit boogs --- CMakeLists.txt | 4 +- src/backend/Core.cpp | 22 +-- src/backend/Core.hpp | 4 +- src/backend/core/BaseCPU.hpp | 2 +- src/backend/core/Interpreter.cpp | 6 +- src/backend/core/Interpreter.hpp | 10 +- src/backend/core/JIT.cpp | 72 +++++---- src/backend/core/JIT.hpp | 204 +++++++++++++------------- src/backend/core/RSP.hpp | 16 +- src/backend/core/jit/instructions.cpp | 34 ++--- 10 files changed, 195 insertions(+), 179 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 84090a07..6b61ed8f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,7 @@ if(APPLE) enable_language(OBJC) endif() +set(VULKAN_VALIDATION FALSE) set(SANITIZERS FALSE) set(CMAKE_CXX_STANDARD 23) set(CMAKE_CXX_STANDARD_REQUIRED ON) @@ -102,7 +103,8 @@ if (HAS_SIMD) add_compile_options(${SIMD_FLAG}) endif () -if (${CMAKE_BUILD_TYPE} MATCHES Debug) +if (${CMAKE_BUILD_TYPE} MATCHES Debug AND VULKAN_VALIDATION) + message("VALIDATION LAYERS: ON") add_compile_definitions(VULKAN_DEBUG) endif () diff --git a/src/backend/Core.cpp b/src/backend/Core.cpp index 641e642c..e3edd5e7 100644 --- a/src/backend/Core.cpp +++ b/src/backend/Core.cpp @@ -5,14 +5,14 @@ namespace n64 { Core::Core() { - auto cpuType = Options::GetInstance().GetValue("cpu", "type"); - if (cpuType == "interpreter") { + const auto selectedCpu = Options::GetInstance().GetValue("cpu", "type"); + if (selectedCpu == "interpreter") { cpuType = Interpreted; - cpu = std::make_unique(parallel, *mem, regs); - } else if(cpuType == "jit") { + cpu = std::make_unique(*mem, regs); + } else if(selectedCpu == "jit") { #ifndef __aarch64__ cpuType = DynamicRecompiler; - cpu = std::make_unique(parallel, *mem, regs); + cpu = std::make_unique(*mem, regs); #else panic("JIT currently unsupported on aarch64"); #endif @@ -62,11 +62,11 @@ void Core::LoadROM(const std::string &rom_) { romLoaded = true; } -int Core::StepCPU() { +u32 Core::StepCPU() { return cpu->Step() + regs.PopStalledCycles(); } -void Core::StepRSP(int cpuCycles) { +void Core::StepRSP(const u32 cpuCycles) { MMIO &mmio = mem->mmio; if (mmio.rsp.spStatus.halt) { @@ -75,10 +75,10 @@ void Core::StepRSP(int cpuCycles) { return; } - static constexpr int cpuRatio = 3, rspRatio = 2; + static constexpr u32 cpuRatio = 3, rspRatio = 2; regs.steps += cpuCycles; - int sets = regs.steps / cpuRatio; + const auto sets = regs.steps / cpuRatio; mmio.rsp.steps += sets * rspRatio; regs.steps -= sets * cpuRatio; @@ -88,7 +88,7 @@ void Core::StepRSP(int cpuCycles) { } } -void Core::Run(float volumeL, float volumeR) { +void Core::Run(const float volumeL, const float volumeR) { MMIO &mmio = mem->mmio; bool broken = false; @@ -102,7 +102,7 @@ void Core::Run(float volumeL, float volumeR) { } while(cycles < mem->mmio.vi.cyclesPerHalfline) { - u32 taken = StepCPU(); + const u32 taken = StepCPU(); cycles += taken; if((broken = breakpoints.contains(regs.nextPC))) diff --git a/src/backend/Core.hpp b/src/backend/Core.hpp index af082567..6df12fcf 100644 --- a/src/backend/Core.hpp +++ b/src/backend/Core.hpp @@ -29,8 +29,8 @@ struct Core { return *GetInstance().mem; } - int StepCPU(); - void StepRSP(int cpuCycles); + u32 StepCPU(); + void StepRSP(u32 cpuCycles); void Stop(); void Reset(); void LoadROM(const std::string &); diff --git a/src/backend/core/BaseCPU.hpp b/src/backend/core/BaseCPU.hpp index 74c6ce32..0b4d01c1 100644 --- a/src/backend/core/BaseCPU.hpp +++ b/src/backend/core/BaseCPU.hpp @@ -6,7 +6,7 @@ namespace n64 { struct BaseCPU { virtual ~BaseCPU() = default; - virtual int Step() = 0; + virtual u32 Step() = 0; virtual void Reset() = 0; }; } // namespace n64 diff --git a/src/backend/core/Interpreter.cpp b/src/backend/core/Interpreter.cpp index 0903c88e..a389dd19 100644 --- a/src/backend/core/Interpreter.cpp +++ b/src/backend/core/Interpreter.cpp @@ -1,7 +1,7 @@ #include namespace n64 { -Interpreter::Interpreter(ParallelRDP& parallel, Mem& mem, Registers& regs) : mem(mem), regs(regs) {} +Interpreter::Interpreter(Mem& mem, Registers& regs) : regs(regs), mem(mem) {} bool Interpreter::ShouldServiceInterrupt() const { const bool interrupts_pending = (regs.cop0.status.im & regs.cop0.cause.interruptPending) != 0; @@ -12,7 +12,7 @@ bool Interpreter::ShouldServiceInterrupt() const { return interrupts_pending && interrupts_enabled && !currently_handling_exception && !currently_handling_error; } -void Interpreter::CheckCompareInterrupt() { +void Interpreter::CheckCompareInterrupt() const { regs.cop0.count++; regs.cop0.count &= 0x1FFFFFFFF; if (regs.cop0.count == static_cast(regs.cop0.compare) << 1) { @@ -21,7 +21,7 @@ void Interpreter::CheckCompareInterrupt() { } } -int Interpreter::Step() { +u32 Interpreter::Step() { CheckCompareInterrupt(); regs.prevDelaySlot = regs.delaySlot; diff --git a/src/backend/core/Interpreter.hpp b/src/backend/core/Interpreter.hpp index 38dd75ee..1bac7a42 100644 --- a/src/backend/core/Interpreter.hpp +++ b/src/backend/core/Interpreter.hpp @@ -6,10 +6,10 @@ namespace n64 { struct Core; -struct Interpreter : BaseCPU { - explicit Interpreter(ParallelRDP&, Mem&, Registers&); +struct Interpreter final : BaseCPU { + explicit Interpreter(Mem&, Registers&); ~Interpreter() override = default; - int Step() override; + u32 Step() override; void Reset() override { cop2Latch = {}; @@ -22,8 +22,8 @@ private: friend struct Cop1; #define check_address_error(mask, vaddr) \ (((!regs.cop0.is64BitAddressing) && (s32)(vaddr) != (vaddr)) || (((vaddr) & (mask)) != 0)) - bool ShouldServiceInterrupt() const; - void CheckCompareInterrupt(); + [[nodiscard]] bool ShouldServiceInterrupt() const; + void CheckCompareInterrupt() const; void cop2Decode(Instruction); void special(Instruction); diff --git a/src/backend/core/JIT.cpp b/src/backend/core/JIT.cpp index 49cb1eed..33706440 100644 --- a/src/backend/core/JIT.cpp +++ b/src/backend/core/JIT.cpp @@ -3,7 +3,7 @@ namespace n64 { #ifndef __aarch64__ -JIT::JIT(ParallelRDP& parallel, Mem& mem, Registers& regs) : mem(mem), regs(regs) { +JIT::JIT(Mem& mem, Registers& regs) : regs(regs), mem(mem) { regs.SetJIT(this); blockCache.resize(kUpperSize); if (cs_open(CS_ARCH_MIPS, static_cast(CS_MODE_MIPS64 | CS_MODE_BIG_ENDIAN), &disassemblerMips) != @@ -25,7 +25,7 @@ bool JIT::ShouldServiceInterrupt() const { return interrupts_pending && interrupts_enabled && !currently_handling_exception && !currently_handling_error; } -void JIT::CheckCompareInterrupt() { +void JIT::CheckCompareInterrupt() const { regs.cop0.count++; regs.cop0.count &= 0x1FFFFFFFF; if (regs.cop0.count == static_cast(regs.cop0.compare) << 1) { @@ -63,19 +63,23 @@ u32 JIT::FetchInstruction() { return 0; } - return Core::GetMem().Read(paddr); + const u32 instr = Core::GetMem().Read(paddr); + + info("{}", Disassembler::GetInstance().DisassembleSimple(paddr, instr).full); + + return instr; } -void JIT::SetPC32(s32 val) { +void JIT::SetPC32(const s32 val) { code.mov(code.SCR1, REG(qword, pc)); code.mov(REG(qword, oldPC), code.SCR1); - code.mov(code.SCR1, s64(val)); + code.mov(code.SCR1, val); code.mov(REG(qword, pc), code.SCR1); - code.mov(code.SCR1, s64(val) + 4); + code.mov(code.SCR1, val + 4); code.mov(REG(qword, nextPC), code.SCR1); } -void JIT::SetPC64(s64 val) { +void JIT::SetPC64(const s64 val) { code.mov(code.SCR1, REG(qword, pc)); code.mov(REG(qword, oldPC), code.SCR1); code.mov(code.SCR1, val); @@ -101,7 +105,7 @@ void JIT::SetPC64(const Xbyak::Reg64& val) { code.mov(REG(qword, nextPC), val); } -int JIT::Step() { +u32 JIT::Step() { blockOldPC = regs.oldPC; blockPC = regs.pc; blockNextPC = regs.nextPC; @@ -111,15 +115,15 @@ int JIT::Step() { /*regs.cop0.HandleTLBException(blockPC); regs.cop0.FireException(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD), 0, blockPC); return 1;*/ - Util::Error::GetInstance().Throw( - {Util::Error::Severity::NON_FATAL}, {Util::Error::Type::UNHANDLED_EXCEPTION}, blockPC, {}, - "[JIT]: Unhandled exception TLB exception {} when retrieving PC physical address!", - static_cast(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD))); + Util::Error::GetInstance().Throw({Util::Error::Severity::NON_FATAL}, {Util::Error::Type::UNHANDLED_EXCEPTION}, + blockPC, {}, + "[JIT]: Unhandled exception TLB exception {} when retrieving PC physical address!", + static_cast(Cop0::GetTLBExceptionCode(regs.cop0.tlbError, Cop0::LOAD))); return 0; } - u32 upperIndex = paddr >> kUpperShift; - u32 lowerIndex = paddr & kLowerMask; + const u32 upperIndex = paddr >> kUpperShift; + const u32 lowerIndex = paddr & kLowerMask; if (!blockCache[upperIndex].empty()) { if (blockCache[upperIndex][lowerIndex]) { @@ -130,7 +134,7 @@ int JIT::Step() { blockCache[upperIndex].resize(kLowerSize); } - info("[JIT]: Compiling block @ 0x{:016X}:", blockPC); + info("[JIT]: Compiling block @ 0x{:016X}:", static_cast(blockPC)); const auto blockInfo = code.getCurr(); const auto block = code.getCurr(); blockCache[upperIndex][lowerIndex] = block; @@ -147,8 +151,12 @@ int JIT::Step() { code.mov(code.rbp, reinterpret_cast(this)); // Load context pointer cs_insn *insn; - info("\tMIPS code (guest PC = 0x{:016X}):", blockPC); + info("\tMIPS code (guest PC = 0x{:016X}):", static_cast(blockPC)); while (!instrEndsBlock) { + code.mov(code.SCR1, REG(byte, delaySlot)); + code.mov(REG(byte, prevDelaySlot), code.SCR1); + code.mov(REG(byte, delaySlot), 0); + // CheckCompareInterrupt(); paddr = 0; @@ -194,6 +202,7 @@ int JIT::Step() { instructionsInBlock++; const u32 delay_instruction = FetchInstruction(); + instrEndsBlock = InstrEndsBlock(delay_instruction); if(instrEndsBlock) { Util::Error::GetInstance().Throw( @@ -209,26 +218,31 @@ int JIT::Step() { Emit(delay_instruction); Emit(instruction); - - if(!regs.delaySlot) { - code.mov(code.SCR1, blockOldPC); - code.mov(REG(qword, oldPC), code.SCR1); - code.mov(code.SCR1, blockPC); - code.mov(REG(qword, pc), code.SCR1); - code.mov(code.SCR1, blockNextPC); - code.mov(REG(qword, nextPC), code.SCR1); - } + + Xbyak::Label clearDelaySlot; + + code.mov(code.SCR1, REG(byte, delaySlot)); + code.cmp(code.SCR1, 0); + code.jne(clearDelaySlot); + code.mov(code.SCR1, blockOldPC); + code.mov(REG(qword, oldPC), code.SCR1); + code.mov(code.SCR1, blockPC); + code.mov(REG(qword, pc), code.SCR1); + code.mov(code.SCR1, blockNextPC); + code.mov(REG(qword, nextPC), code.SCR1); + code.L(clearDelaySlot); + code.mov(REG(byte, delaySlot), 0); code.mov(code.rax, instructionsInBlock); code.pop(code.rbp); code.add(code.rsp, 8); code.ret(); code.setProtectModeRE(); - static auto blockInfoSize = 0; + static size_t blockInfoSize = 0; blockInfoSize = code.getSize() - blockInfoSize; - info("\tX86 code (block address = 0x{:016X}):", (uintptr_t)block); - auto count = cs_disasm(disassemblerX86, blockInfo, blockInfoSize, (uintptr_t)block, 0, &insn); + info("\tX86 code (block address = 0x{:016X}):", reinterpret_cast(block)); + const auto count = cs_disasm(disassemblerX86, blockInfo, blockInfoSize, reinterpret_cast(block), 0, &insn); if (count > 0) { for (size_t j = 0; j < count; j++) { info("\t\t0x{:016X}:\t{}\t\t{}", insn[j].address, insn[j].mnemonic, insn[j].op_str); @@ -241,7 +255,7 @@ int JIT::Step() { } #endif -void JIT::DumpBlockCacheToDisk() { +void JIT::DumpBlockCacheToDisk() const { 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 adc2c6da..87aa7030 100644 --- a/src/backend/core/JIT.hpp +++ b/src/backend/core/JIT.hpp @@ -16,15 +16,15 @@ static constexpr u32 kUpperSize = kAddressSpaceSize >> kUpperShift; // 0x800000 static constexpr u32 kLowerSize = 0x100; // 0x80 static constexpr u32 kCodeCacheSize = 32_mb; static constexpr u32 kCodeCacheAllocSize = kCodeCacheSize + 4_kb; -#define REG(acc, x) code.acc[reinterpret_cast(®s.x)] +#define REG(acc, x) code.acc[code.rbp + (reinterpret_cast(®s.x) - reinterpret_cast(this))] #ifdef __aarch64__ struct JIT : BaseCPU {}; #else -struct JIT : BaseCPU { - explicit JIT(ParallelRDP&, Mem&, Registers&); +struct JIT final : BaseCPU { + explicit JIT(Mem&, Registers&); ~JIT() override = default; - int Step() override; + u32 Step() override; void Reset() override { code.reset(); @@ -32,7 +32,7 @@ struct JIT : BaseCPU { blockCache.resize(kUpperSize); } - void DumpBlockCacheToDisk(); + void DumpBlockCacheToDisk() const; void InvalidateBlock(u32); private: @@ -40,13 +40,13 @@ private: Mem& mem; Xbyak::CodeGenerator code{kCodeCacheAllocSize}; u64 cop2Latch{}; - u64 blockOldPC = 0, blockPC = 0, blockNextPC = 0; + s64 blockOldPC = 0, blockPC = 0, blockNextPC = 0; friend struct Cop1; friend struct Registers; using BlockFn = int (*)(); std::vector> blockCache; Xbyak::Label branch_likely_not_taken; - csh disassemblerMips, disassemblerX86; + csh disassemblerMips{}, disassemblerX86{}; template Xbyak::Address GPR(const size_t index) const { @@ -108,89 +108,89 @@ private: (((!regs.cop0.is64BitAddressing) && (s32)(vaddr) != (vaddr)) || (((vaddr) & (mask)) != 0)) [[nodiscard]] bool ShouldServiceInterrupt() const; - void CheckCompareInterrupt(); + void CheckCompareInterrupt() const; u32 FetchInstruction(); - void Emit(const Instruction); - void special(const Instruction); - void regimm(const Instruction); - void add(const Instruction); - void addu(const Instruction); - void addi(const Instruction); - void addiu(const Instruction); - void andi(const Instruction); - void and_(const Instruction); + void Emit(Instruction); + void special(Instruction); + void regimm(Instruction); + void add(Instruction); + void addu(Instruction); + void addi(Instruction); + void addiu(Instruction); + void andi(Instruction); + void and_(Instruction); void branch_constant(bool cond, s64 offset); void branch_likely_constant(bool cond, s64 offset); void branch_abs_constant(bool cond, s64 address); - void bltz(const Instruction); - void bgez(const Instruction); - void bltzl(const Instruction); - void bgezl(const Instruction); - void bltzal(const Instruction); - void bgezal(const Instruction); - void bltzall(const Instruction); - void bgezall(const Instruction); - void beq(const Instruction); - void beql(const Instruction); - void bne(const Instruction); - void bnel(const Instruction); - void blez(const Instruction); - void blezl(const Instruction); - void bgtz(const Instruction); - void bgtzl(const Instruction); - void bfc1(const Instruction); - void blfc1(const Instruction); - void bfc0(const Instruction); - void blfc0(const Instruction); - void dadd(const Instruction); - void daddu(const Instruction); - void daddi(const Instruction); - void daddiu(const Instruction); - void ddiv(const Instruction); - void ddivu(const Instruction); - void div(const Instruction); - void divu(const Instruction); - void dmult(const Instruction); - void dmultu(const Instruction); - void dsll(const Instruction); - void dsllv(const Instruction); - void dsll32(const Instruction); - void dsra(const Instruction); - void dsrav(const Instruction); - void dsra32(const Instruction); - void dsrl(const Instruction); - void dsrlv(const Instruction); - void dsrl32(const Instruction); - void dsub(const Instruction); - void dsubu(const Instruction); - void j(const Instruction); - void jr(const Instruction); - void jal(const Instruction); - void jalr(const Instruction); - void lui(const Instruction); - void lbu(const Instruction); - void lb(const Instruction); - void ld(const Instruction); - void ldc1(const Instruction); - void ldl(const Instruction); - void ldr(const Instruction); - void lh(const Instruction); - void lhu(const Instruction); - void ll(const Instruction); - void lld(const Instruction); - void lw(const Instruction); - void lwc1(const Instruction); - void lwl(const Instruction); - void lwu(const Instruction); - void lwr(const Instruction); - void mfhi(const Instruction); - void mflo(const Instruction); - void mult(const Instruction); - void multu(const Instruction); - void mthi(const Instruction); - void mtlo(const Instruction); - void nor(const Instruction); + void bltz(Instruction); + void bgez(Instruction); + void bltzl(Instruction); + void bgezl(Instruction); + void bltzal(Instruction); + void bgezal(Instruction); + void bltzall(Instruction); + void bgezall(Instruction); + void beq(Instruction); + void beql(Instruction); + void bne(Instruction); + void bnel(Instruction); + void blez(Instruction); + void blezl(Instruction); + void bgtz(Instruction); + void bgtzl(Instruction); + void bfc1(Instruction); + void blfc1(Instruction); + void bfc0(Instruction); + void blfc0(Instruction); + void dadd(Instruction); + void daddu(Instruction); + void daddi(Instruction); + void daddiu(Instruction); + void ddiv(Instruction); + void ddivu(Instruction); + void div(Instruction); + void divu(Instruction); + void dmult(Instruction); + void dmultu(Instruction); + void dsll(Instruction); + void dsllv(Instruction); + void dsll32(Instruction); + void dsra(Instruction); + void dsrav(Instruction); + void dsra32(Instruction); + void dsrl(Instruction); + void dsrlv(Instruction); + void dsrl32(Instruction); + void dsub(Instruction); + void dsubu(Instruction); + void j(Instruction); + void jr(Instruction); + void jal(Instruction); + void jalr(Instruction); + void lui(Instruction); + void lbu(Instruction); + void lb(Instruction); + void ld(Instruction); + void ldc1(Instruction); + void ldl(Instruction); + void ldr(Instruction); + void lh(Instruction); + void lhu(Instruction); + void ll(Instruction); + void lld(Instruction); + void lw(Instruction); + void lwc1(Instruction); + void lwl(Instruction); + void lwu(Instruction); + void lwr(Instruction); + void mfhi(Instruction); + void mflo(Instruction); + void mult(Instruction); + void multu(Instruction); + void mthi(Instruction); + void mtlo(Instruction); + void nor(Instruction); void sb(const Instruction) { Util::Error::GetInstance().Throw( {Util::Error::Severity::NON_FATAL}, {Util::Error::Type::UNHANDLED_INSTRUCTION}, @@ -231,7 +231,7 @@ private: {Util::Error::Severity::NON_FATAL}, {Util::Error::Type::UNHANDLED_INSTRUCTION}, blockPC, {}, "[JIT]: Unhandled 'sh'!"); } - void sw(const Instruction); + void sw(Instruction); void swl(const Instruction) { Util::Error::GetInstance().Throw( {Util::Error::Severity::NON_FATAL}, {Util::Error::Type::UNHANDLED_INSTRUCTION}, @@ -242,32 +242,32 @@ private: {Util::Error::Severity::NON_FATAL}, {Util::Error::Type::UNHANDLED_INSTRUCTION}, blockPC, {}, "[JIT]: Unhandled 'swr'!"); } - void slti(const Instruction); - void sltiu(const Instruction); - void slt(const Instruction); - void sltu(const Instruction); - void sll(const Instruction); - void sllv(const Instruction); - void sub(const Instruction); - void subu(const Instruction); + void slti(Instruction); + void sltiu(Instruction); + void slt(Instruction); + void sltu(Instruction); + void sll(Instruction); + void sllv(Instruction); + void sub(Instruction); + void subu(Instruction); void swc1(const Instruction) { Util::Error::GetInstance().Throw( {Util::Error::Severity::NON_FATAL}, {Util::Error::Type::JIT_BRANCH_INSIDE_DELAY_SLOT}, blockPC, {}, "[JIT]: Unhandled case of branch from delay slot!"); } - void sra(const Instruction); - void srav(const Instruction); - void srl(const Instruction); - void srlv(const Instruction); + void sra(Instruction); + void srav(Instruction); + void srl(Instruction); + void srlv(Instruction); void trap(bool) { Util::Error::GetInstance().Throw( {Util::Error::Severity::NON_FATAL}, {Util::Error::Type::JIT_BRANCH_INSIDE_DELAY_SLOT}, blockPC, {}, "[JIT]: Unhandled case of branch from delay slot!"); } - void or_(const Instruction); - void ori(const Instruction); - void xor_(const Instruction); - void xori(const Instruction); + void or_(Instruction); + void ori(Instruction); + void xor_(Instruction); + void xori(Instruction); }; #endif } // namespace n64 diff --git a/src/backend/core/RSP.hpp b/src/backend/core/RSP.hpp index 6963eb32..48214cd5 100644 --- a/src/backend/core/RSP.hpp +++ b/src/backend/core/RSP.hpp @@ -135,7 +135,7 @@ struct RSP { void SetVTE(const VPR &vt, u8 e); auto Read(u32 addr) -> u32; void Write(u32 addr, u32 val); - void Exec(const Instruction instr); + void Exec(Instruction instr); SPStatus spStatus{}; u16 oldPC{}, pc{}, nextPC{}; SPDMASPAddr spDMASPAddr{}; @@ -151,7 +151,7 @@ struct RSP { VPR vce{}; s16 divIn{}, divOut{}; bool divInLoaded = false; - int steps = 0; + u32 steps = 0; struct { VPR h{}, m{}, l{}; @@ -257,12 +257,12 @@ struct RSP { FORCE_INLINE void ReleaseSemaphore() { semaphore = false; } - void special(const Instruction instr); - void regimm(const Instruction instr); - void lwc2(const Instruction instr); - void swc2(const Instruction instr); - void cop2(const Instruction instr); - void cop0(const Instruction instr); + void special(Instruction instr); + void regimm(Instruction instr); + void lwc2(Instruction instr); + void swc2(Instruction instr); + void cop2(Instruction instr); + void cop0(Instruction instr); void add(Instruction instr); void addi(Instruction instr); diff --git a/src/backend/core/jit/instructions.cpp b/src/backend/core/jit/instructions.cpp index 78edde2e..1fe341e9 100644 --- a/src/backend/core/jit/instructions.cpp +++ b/src/backend/core/jit/instructions.cpp @@ -192,35 +192,35 @@ void JIT::blfc1(const Instruction instr) { } void JIT::BranchNotTaken() {} -void JIT::BranchTaken(s64 offs) { + +void JIT::BranchTaken(const s64 offs) { code.mov(code.SCR1, REG(qword, pc)); code.add(code.SCR1, offs); - SetPC64(offs); + SetPC64(code.SCR1); } void JIT::BranchTaken(const Xbyak::Reg64 &offs) { code.mov(code.SCR1, REG(qword, pc)); code.add(code.SCR1, offs); - SetPC64(offs); + SetPC64(code.SCR1); } -void JIT::BranchAbsTaken(s64 addr) { - code.add(code.SCR1, addr); - code.mov(REG(qword, nextPC), code.SCR1); +void JIT::BranchAbsTaken(const s64 addr) { + SetPC64(addr); } void JIT::BranchAbsTaken(const Xbyak::Reg64 &addr) { - code.mov(REG(qword, nextPC), addr); + SetPC64(addr); } -void JIT::branch_constant(const bool cond, s64 offset) { +void JIT::branch_constant(const bool cond, const s64 offset) { if(cond) { regs.delaySlot = true; BranchTaken(offset); } } -void JIT::branch_likely_constant(bool cond, s64 offset) { +void JIT::branch_likely_constant(const bool cond, const s64 offset) { if(cond) { regs.delaySlot = true; BranchTaken(offset); @@ -229,7 +229,7 @@ void JIT::branch_likely_constant(bool cond, s64 offset) { } } -void JIT::branch_abs_constant(bool cond, s64 address) { +void JIT::branch_abs_constant(const bool cond, const s64 address) { if(cond) { regs.delaySlot = true; BranchAbsTaken(address); @@ -238,7 +238,7 @@ void JIT::branch_abs_constant(bool cond, s64 address) { #define branch(offs, cond) do { \ Xbyak::Label taken, not_taken; \ - code.j##cond(taken); \ + code.j## cond(taken); \ code.jmp(not_taken); \ code.L(taken); \ BranchTaken(offs); \ @@ -247,7 +247,7 @@ void JIT::branch_abs_constant(bool cond, s64 address) { #define branch_abs(addr, cond) do { \ Xbyak::Label taken, not_taken; \ - code.j##cond(taken); \ + code.j## cond(taken); \ code.jmp(not_taken); \ code.L(taken); \ BranchAbsTaken(addr); \ @@ -256,7 +256,7 @@ void JIT::branch_abs_constant(bool cond, s64 address) { #define branch_likely(offs, cond) do { \ Xbyak::Label taken, not_taken; \ - code.j##cond(taken); \ + code.j## cond(taken); \ code.jmp(not_taken); \ code.L(taken); \ BranchTaken(offs); \ @@ -266,7 +266,7 @@ void JIT::branch_abs_constant(bool cond, s64 address) { void JIT::bltz(const Instruction instr) { const s16 imm = instr; - const s64 offset = u64((s64)imm) << 2; + const s64 offset = static_cast(imm) << 2; if (regs.IsRegConstant(instr.rs())) { branch_constant(regs.Read(instr.rs()) < 0, offset); return; @@ -435,7 +435,7 @@ void JIT::beql(const Instruction instr) { void JIT::bne(const Instruction instr) { const s16 imm = instr; - const s64 offset = u64((s64)imm) << 2; + const s64 offset = static_cast(imm) << 2; if (regs.IsRegConstant(instr.rs()) && regs.IsRegConstant(instr.rt())) { branch_constant(regs.Read(instr.rs()) != regs.Read(instr.rt()), offset); return; @@ -857,13 +857,13 @@ void JIT::dsubu(const Instruction instr) { void JIT::j(const Instruction instr) { const s32 target = (instr & 0x3ffffff) << 2; - const s64 address = (blockOldPC & ~0xfffffff) | target; + const s64 address = blockOldPC & ~0xfffffff | target; branch_abs_constant(true, address); } void JIT::jr(const Instruction instr) { if (regs.IsRegConstant(instr.rs())) { - const u64 address = regs.Read(instr.rs()); + const auto address = regs.Read(instr.rs()); branch_abs_constant(true, address); return; }