From 1a338de8b90478e89b21bebfa82171a74eeafad3 Mon Sep 17 00:00:00 2001 From: SimoneN64 Date: Sat, 19 Aug 2023 16:12:51 +0200 Subject: [PATCH] more work --- src/backend/core/JIT.hpp | 23 +++++++--- src/backend/core/JIT/decode.cpp | 63 +++++++++++++++++++++------ src/backend/core/JIT/instructions.cpp | 16 ++++--- 3 files changed, 76 insertions(+), 26 deletions(-) diff --git a/src/backend/core/JIT.hpp b/src/backend/core/JIT.hpp index 33a03329..71159fe1 100644 --- a/src/backend/core/JIT.hpp +++ b/src/backend/core/JIT.hpp @@ -81,12 +81,23 @@ private: void andi(u32); void and_(u32); void emitCondition(const std::string&, BranchCond); - void branch(Xbyak::Operand, Xbyak::Operand, s64, BranchCond); - void branch_likely(Xbyak::Operand, Xbyak::Operand, s64, BranchCond); - void b(u32, Xbyak::Operand, Xbyak::Operand, BranchCond); - void blink(u32, Xbyak::Operand, Xbyak::Operand, BranchCond); - void bl(u32, Xbyak::Operand, Xbyak::Operand, BranchCond); - void bllink(u32, Xbyak::Operand, Xbyak::Operand, BranchCond); + template + void branch(const Xbyak::Operand&, const T&, s64, BranchCond); + + template + void branch_likely(const Xbyak::Operand&, const T&, s64, BranchCond); + + template + void b(u32, const Xbyak::Operand&, const T&, BranchCond); + + template + void blink(u32, const Xbyak::Operand&, const T&, BranchCond); + + template + void bl(u32, const Xbyak::Operand&, const T&, BranchCond); + + template + void bllink(u32, const Xbyak::Operand&, const T&, BranchCond); void dadd(u32); void daddu(u32); void daddi(u32); diff --git a/src/backend/core/JIT/decode.cpp b/src/backend/core/JIT/decode.cpp index 7f5743c8..f43e5ae5 100644 --- a/src/backend/core/JIT/decode.cpp +++ b/src/backend/core/JIT/decode.cpp @@ -71,20 +71,44 @@ void JIT::regimm(u32 instr) { u8 mask = ((instr >> 16) & 0x1F); // 000r_rccc switch (mask) { // TODO: named constants for clearer code - case 0x00: b(instr, regs.gpr[RS(instr)] < 0); break; - case 0x01: b(instr, regs.gpr[RS(instr)] >= 0); break; - case 0x02: bl(instr, regs.gpr[RS(instr)] < 0); break; - case 0x03: bl(instr, regs.gpr[RS(instr)] >= 0); break; + case 0x00: { + mov(rax, GPR(RS(instr))); + b(instr, rax, 0, LT); + } break; + case 0x01: { + mov(rax, GPR(RS(instr))); + b(instr, rax, 0, GE); + } break; + case 0x02: { + mov(rax, GPR(RS(instr))); + bl(instr, rax, 0, LT); + } break; + case 0x03: { + mov(rax, GPR(RS(instr))); + bl(instr, rax, 0, GE); + } break; case 0x08: trap(regs.gpr[RS(instr)] >= s64(s16(instr))); break; case 0x09: trap(u64(regs.gpr[RS(instr)]) >= u64(s64(s16(instr)))); break; case 0x0A: trap(regs.gpr[RS(instr)] < s64(s16(instr))); break; case 0x0B: trap(u64(regs.gpr[RS(instr)]) < u64(s64(s16(instr)))); break; case 0x0C: trap(regs.gpr[RS(instr)] == s64(s16(instr))); break; case 0x0E: trap(regs.gpr[RS(instr)] != s64(s16(instr))); break; - case 0x10: blink(instr, regs.gpr[RS(instr)] < 0); break; - case 0x11: blink(instr, regs.gpr[RS(instr)] >= 0); break; - case 0x12: bllink(instr, regs.gpr[RS(instr)] < 0); break; - case 0x13: bllink(instr, regs.gpr[RS(instr)] >= 0); break; + case 0x10: { + mov(rax, GPR(RS(instr))); + blink(instr, rax, 0, LT); + } break; + case 0x11: { + mov(rax, GPR(RS(instr))); + blink(instr, rax, 0, GE); + } break; + case 0x12: { + mov(rax, GPR(RS(instr))); + bllink(instr, rax, 0, LT); + } break; + case 0x13: { + mov(rax, GPR(RS(instr))); + bllink(instr, rax, 0, GE); + } break; default: Util::panic("Unimplemented regimm {} {} ({:08X}) (pc: {:016X})", (mask >> 3) & 3, mask & 7, instr, (u64)regs.oldPC); } @@ -115,13 +139,24 @@ void JIT::Emit(u32 instr) { case 0x01: regimm(instr); break; case 0x02: j(instr); break; case 0x03: jal(instr); break; - case 0x04: b(instr, regs.gpr[RS(instr)] == regs.gpr[RT(instr)]); break; - case 0x05: { - //fmt::print("RS: {:016X}, RT: {:016X}", (u64)regs.gpr[RS(instr)], (u64)regs.gpr[RT(instr)]); - b(instr, regs.gpr[RS(instr)] != regs.gpr[RT(instr)]); + case 0x04: { + mov(rax, GPR(RS(instr))); + mov(rcx, GPR(RT(instr))); + b(instr, rax, rcx, EQ); + } break; + case 0x05: { + mov(rax, GPR(RS(instr))); + mov(rcx, GPR(RT(instr))); + b(instr, rax, rcx, NE); + } break; + case 0x06: { + mov(rax, GPR(RS(instr))); + b(instr, rax, 0, LE); + } break; + case 0x07: { + mov(rax, GPR(RS(instr))); + b(instr, rax, 0, GT); } break; - case 0x06: b(instr, regs.gpr[RS(instr)] <= 0); break; - case 0x07: b(instr, regs.gpr[RS(instr)] > 0); break; case 0x08: addi(instr); break; case 0x09: addiu(instr); break; case 0x0A: slti(instr); break; diff --git a/src/backend/core/JIT/instructions.cpp b/src/backend/core/JIT/instructions.cpp index a6fd5102..064c71a5 100644 --- a/src/backend/core/JIT/instructions.cpp +++ b/src/backend/core/JIT/instructions.cpp @@ -166,7 +166,8 @@ void JIT::emitCondition(const std::string& name, BranchCond cond) { } } -void JIT::branch(Xbyak::Operand op1, Xbyak::Operand op2, s64 offset, BranchCond cond) { +template +void JIT::branch(const Xbyak::Operand& op1, const T& op2, s64 offset, BranchCond cond) { cmp(op1, op2); emitCondition("false", cond); @@ -177,7 +178,10 @@ void JIT::branch(Xbyak::Operand op1, Xbyak::Operand op2, s64 offset, BranchCond L("false"); } -void JIT::branch_likely(Xbyak::Operand op1, Xbyak::Operand op2, s64 offset, BranchCond cond) { +template void JIT::branch(const Xbyak::Operand& op1, const Xbyak::Operand& op2, s64 offset, BranchCond cond); +template void JIT::branch(const Xbyak::Operand& op1, const int& op2, s64 offset, BranchCond cond); + +void JIT::branch_likely(const Xbyak::Operand& op1, const Xbyak::Operand& op2, s64 offset, BranchCond cond) { mov(rax, qword[rdi + offsetof(Registers, pc)]); cmp(op1, op2); emitCondition("false", cond); @@ -196,13 +200,13 @@ void JIT::branch_likely(Xbyak::Operand op1, Xbyak::Operand op2, s64 offset, Bran L("exit"); } -void JIT::b(u32 instr, Xbyak::Operand op1, Xbyak::Operand op2, BranchCond cond) { +void JIT::b(u32 instr, const Xbyak::Operand& op1, const Xbyak::Operand& op2, BranchCond cond) { s16 imm = instr; s64 offset = u64((s64)imm) << 2; branch(op1, op2, offset, cond); } -void JIT::blink(u32 instr, Xbyak::Operand op1, Xbyak::Operand op2, BranchCond cond) { +void JIT::blink(u32 instr, const Xbyak::Operand& op1, const Xbyak::Operand& op2, BranchCond cond) { s16 imm = instr; s64 offset = u64((s64)imm) << 2; mov(rcx, qword[rdi + offsetof(Registers, nextPC)]); @@ -210,13 +214,13 @@ void JIT::blink(u32 instr, Xbyak::Operand op1, Xbyak::Operand op2, BranchCond co branch(op1, op2, offset, cond); } -void JIT::bl(u32 instr, Xbyak::Operand op1, Xbyak::Operand op2, BranchCond cond) { +void JIT::bl(u32 instr, const Xbyak::Operand& op1, const Xbyak::Operand& op2, BranchCond cond) { s16 imm = instr; s64 offset = u64((s64)imm) << 2; branch_likely(op1, op2, offset, cond); } -void JIT::bllink(u32 instr, Xbyak::Operand op1, Xbyak::Operand op2, BranchCond cond) { +void JIT::bllink(u32 instr, const Xbyak::Operand& op1, const Xbyak::Operand& op2, BranchCond cond) { mov(rcx, qword[rdi + offsetof(Registers, nextPC)]); mov(GPR(31), rcx); s16 imm = instr;