From 559e3eaa6e1c6b405bee1a219a11c4155017de12 Mon Sep 17 00:00:00 2001 From: irisz64 Date: Tue, 8 Jul 2025 16:15:39 +0200 Subject: [PATCH] whatever --- src/backend/core/JIT.cpp | 13 ++++- src/backend/core/JIT.hpp | 39 +++++++++---- src/backend/core/jit/instructions.cpp | 79 +++++++++++++++++++++++++-- 3 files changed, 115 insertions(+), 16 deletions(-) diff --git a/src/backend/core/JIT.cpp b/src/backend/core/JIT.cpp index 3f796669..e71a5e18 100644 --- a/src/backend/core/JIT.cpp +++ b/src/backend/core/JIT.cpp @@ -115,7 +115,7 @@ int JIT::Step() { blockPC = blockNextPC; blockNextPC += 4; - if(instrEndsBlock = InstrEndsBlock(instruction)) + if((instrEndsBlock = InstrEndsBlock(instruction))) continue; /*u32 bswapped = bswap(instruction); @@ -145,10 +145,19 @@ int JIT::Step() { blockOldPC = blockPC; blockPC = blockNextPC; blockNextPC += 4; - + 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); + } code.mov(code.rax, instructionsInBlock); code.pop(code.rbp); diff --git a/src/backend/core/JIT.hpp b/src/backend/core/JIT.hpp index 73f8985e..3f0cbb2a 100644 --- a/src/backend/core/JIT.hpp +++ b/src/backend/core/JIT.hpp @@ -100,21 +100,40 @@ private: } void SetPC32(s32 val) { - code.mov(code.rax, REG(qword, pc)); - code.mov(REG(qword, oldPC), code.rax); - code.mov(REG(qword, pc), (s64)val); - code.mov(REG(qword, nextPC), (s64)val + 4); + code.mov(code.SCR1, REG(qword, pc)); + code.mov(REG(qword, oldPC), code.SCR1); + code.mov(code.SCR1, s64(val)); + code.mov(REG(qword, pc), code.SCR1); + code.mov(code.SCR1, s64(val) + 4); + code.mov(REG(qword, nextPC), code.SCR1); } void SetPC64(s64 val) { - code.mov(code.rax, REG(qword, pc)); - code.mov(REG(qword, oldPC), code.rax); - code.mov(REG(qword, pc), val); - code.mov(REG(qword, nextPC), val + 4); + code.mov(code.SCR1, REG(qword, pc)); + code.mov(REG(qword, oldPC), code.SCR1); + code.mov(code.SCR1, val); + code.mov(REG(qword, pc), code.SCR1); + code.mov(code.SCR1, val + 4); + code.mov(REG(qword, nextPC), code.SCR1); + } + + void SetPC32(const Xbyak::Reg32& val) { + code.mov(code.SCR1, REG(qword, pc)); + code.mov(REG(qword, oldPC), code.SCR1); + code.movsxd(val.cvt64(), val); + code.mov(REG(qword, pc), val); + code.add(val, 4); + code.mov(REG(qword, nextPC), val); + } + + void SetPC64(const Xbyak::Reg64& val) { + code.mov(code.SCR1, REG(qword, pc)); + code.mov(REG(qword, oldPC), code.SCR1); + code.mov(REG(qword, pc), val); + code.add(val, 4); + code.mov(REG(qword, nextPC), val); } - void SkipSlot(); - void SkipSlotConstant(); void BranchNotTaken(); void BranchTaken(s64 offs); void BranchTaken(const Xbyak::Reg64 &offs); diff --git a/src/backend/core/jit/instructions.cpp b/src/backend/core/jit/instructions.cpp index 8b846eb4..e749d898 100644 --- a/src/backend/core/jit/instructions.cpp +++ b/src/backend/core/jit/instructions.cpp @@ -191,7 +191,80 @@ void JIT::blfc1(u32 instr) { // code.test(code.al, code.al); // branch_likely(address, nz); } -/* + +void JIT::BranchNotTaken() {} +void JIT::BranchTaken(s64 offs) { + code.mov(code.SCR1, REG(qword, pc)); + code.add(code.SCR1, offs); + SetPC64(offs); +} + +void JIT::BranchTaken(const Xbyak::Reg64 &offs) { + code.mov(code.SCR1, REG(qword, pc)); + code.add(code.SCR1, offs); + SetPC64(offs); +} + +void JIT::BranchAbsTaken(s64 addr) { + code.add(code.SCR1, addr); + code.mov(REG(qword, nextPC), code.SCR1); +} + +void JIT::BranchAbsTaken(const Xbyak::Reg64 &addr) { + code.mov(REG(qword, nextPC), addr); +} + +void JIT::branch_constant(const bool cond, s64 offset) { + if(cond) { + regs.delaySlot = true; + BranchTaken(offset); + } +} + +void JIT::branch_likely_constant(bool cond, s64 offset) { + if(cond) { + regs.delaySlot = true; + BranchTaken(offset); + } else { + SetPC64(blockNextPC); + } +} + +void JIT::branch_abs_constant(bool cond, s64 address) { + if(cond) { + regs.delaySlot = true; + BranchAbsTaken(address); + } +} + +#define branch(offs, cond) do { \ + Xbyak::Label taken, not_taken; \ + code.j##cond(taken); \ + code.jmp(not_taken); \ + code.L(taken); \ + BranchTaken(offs); \ + code.L(not_taken); \ +} while(0) + +#define branch_abs(addr, cond) do { \ + Xbyak::Label taken, not_taken; \ + code.j##cond(taken); \ + code.jmp(not_taken); \ + code.L(taken); \ + BranchAbsTaken(addr); \ + code.L(not_taken); \ +} while(0) + +#define branch_likely(offs, cond) do { \ + Xbyak::Label taken, not_taken; \ + code.j##cond(taken); \ + code.jmp(not_taken); \ + code.L(taken); \ + BranchTaken(offs); \ + code.L(not_taken); \ + SetPC64(blockNextPC); \ +} while(0) + void JIT::bltz(const u32 instr) { const s16 imm = instr; const s64 offset = u64((s64)imm) << 2; @@ -471,7 +544,7 @@ void JIT::bgtzl(const u32 instr) { code.cmp(code.rax, 0); branch_likely(offset, g); } -*/ + void JIT::dadd(u32 instr) { if (regs.IsRegConstant(RS(instr), RT(instr))) { auto rs = regs.Read(RS(instr)); @@ -783,7 +856,6 @@ void JIT::dsubu(u32 instr) { } } -/* void JIT::j(const u32 instr) { const s32 target = (instr & 0x3ffffff) << 2; const s64 address = (blockOldPC & ~0xfffffff) | target; @@ -810,7 +882,6 @@ void JIT::jalr(const u32 instr) { regs.Write(RD(instr), blockNextPC); jr(instr); } -*/ void JIT::lbu(u32 instr) { if (regs.IsRegConstant(RS(instr))) {