From 5444df993ce79bf7e739601a4e815cd323a5b70e Mon Sep 17 00:00:00 2001 From: irisz64 Date: Mon, 1 Sep 2025 09:47:07 +0200 Subject: [PATCH] Instruction struct rewrite in RSP too now --- src/backend/core/Interpreter.hpp | 2 +- src/backend/core/RSP.hpp | 229 +++---- src/backend/core/interpreter/decode.cpp | 4 +- src/backend/core/jit/decode.cpp | 24 +- src/backend/core/jit/instructions.cpp | 8 +- src/backend/core/rsp/decode.cpp | 65 +- src/backend/core/rsp/instructions.cpp | 814 ++++++++++++------------ src/common.hpp | 12 - src/utils/Instruction.hpp | 5 + 9 files changed, 578 insertions(+), 585 deletions(-) diff --git a/src/backend/core/Interpreter.hpp b/src/backend/core/Interpreter.hpp index 02a2bb63..38dd75ee 100644 --- a/src/backend/core/Interpreter.hpp +++ b/src/backend/core/Interpreter.hpp @@ -25,7 +25,7 @@ private: bool ShouldServiceInterrupt() const; void CheckCompareInterrupt(); - void cop2Decode(u32); + void cop2Decode(Instruction); void special(Instruction); void regimm(Instruction); void Exec(Instruction); diff --git a/src/backend/core/RSP.hpp b/src/backend/core/RSP.hpp index e9221389..6963eb32 100644 --- a/src/backend/core/RSP.hpp +++ b/src/backend/core/RSP.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #define RSP_BYTE(addr) (dmem[BYTE_ADDRESS(addr) & 0xFFF]) #define GET_RSP_HALF(addr) ((RSP_BYTE(addr) << 8) | RSP_BYTE((addr) + 1)) @@ -134,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(u32 instr); + void Exec(const Instruction instr); SPStatus spStatus{}; u16 oldPC{}, pc{}, nextPC{}; SPDMASPAddr spDMASPAddr{}; @@ -256,120 +257,120 @@ struct RSP { FORCE_INLINE void ReleaseSemaphore() { semaphore = false; } - void special(const u32 instr); - void regimm(const u32 instr); - void lwc2(const u32 instr); - void swc2(const u32 instr); - void cop2(const u32 instr); - void cop0(const u32 instr); + 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 add(u32 instr); - void addi(u32 instr); - void and_(u32 instr); - void andi(u32 instr); - void b(u32 instr, bool cond); - void blink(u32 instr, bool cond); - void cfc2(u32 instr); - void ctc2(u32 instr); - void lb(u32 instr); - void lh(u32 instr); - void lw(u32 instr); - void lbu(u32 instr); - void lhu(u32 instr); - void lui(u32 instr); - void luv(u32 instr); - void lbv(u32 instr); - void ldv(u32 instr); - void lsv(u32 instr); - void llv(u32 instr); - void lrv(u32 instr); - void lqv(u32 instr); - void lfv(u32 instr); - void lhv(u32 instr); - void ltv(u32 instr); - void lpv(u32 instr); - void j(u32 instr); - void jal(u32 instr); - void jr(u32 instr); - void jalr(u32 instr); - void nor(u32 instr); - void or_(u32 instr); - void ori(u32 instr); - void xor_(u32 instr); - void xori(u32 instr); - void sb(u32 instr); - void sh(u32 instr); - void sw(u32 instr); - void swv(u32 instr); - void sub(u32 instr); - void sbv(u32 instr); - void sdv(u32 instr); - void stv(u32 instr); - void sqv(u32 instr); - void ssv(u32 instr); - void suv(u32 instr); - void slv(u32 instr); - void shv(u32 instr); - void sfv(u32 instr); - void srv(u32 instr); - void spv(u32 instr); - void sllv(u32 instr); - void srlv(u32 instr); - void srav(u32 instr); - void sll(u32 instr); - void srl(u32 instr); - void sra(u32 instr); - void slt(u32 instr); - void sltu(u32 instr); - void slti(u32 instr); - void sltiu(u32 instr); - void vabs(u32 instr); - void vadd(u32 instr); - void vaddc(u32 instr); - void vand(u32 instr); - void vnand(u32 instr); - void vch(u32 instr); - void vcr(u32 instr); - void vcl(u32 instr); - void vmacf(u32 instr); - void vmacu(u32 instr); - void vmacq(u32 instr); - void vmadh(u32 instr); - void vmadl(u32 instr); - void vmadm(u32 instr); - void vmadn(u32 instr); - void vmov(u32 instr); - void vmulf(u32 instr); - void vmulu(u32 instr); - void vmulq(u32 instr); - void vmudl(u32 instr); - void vmudh(u32 instr); - void vmudm(u32 instr); - void vmudn(u32 instr); - void vmrg(u32 instr); - void vlt(u32 instr); - void veq(u32 instr); - void vne(u32 instr); - void vge(u32 instr); - void vrcp(u32 instr); - void vrsq(u32 instr); - void vrcpl(u32 instr); - void vrsql(u32 instr); - void vrndp(u32 instr); - void vrndn(u32 instr); - void vrcph(u32 instr); - void vsar(u32 instr); - void vsub(u32 instr); - void vsubc(u32 instr); - void vxor(u32 instr); - void vnxor(u32 instr); - void vor(u32 instr); - void vnor(u32 instr); - void vzero(u32 instr); - void mfc0(const RDP &rdp, u32 instr); - void mtc0(u32 instr) const; - void mfc2(u32 instr); - void mtc2(u32 instr); + void add(Instruction instr); + void addi(Instruction instr); + void and_(Instruction instr); + void andi(Instruction instr); + void b(Instruction instr, bool cond); + void blink(Instruction instr, bool cond); + void cfc2(Instruction instr); + void ctc2(Instruction instr); + void lb(Instruction instr); + void lh(Instruction instr); + void lw(Instruction instr); + void lbu(Instruction instr); + void lhu(Instruction instr); + void lui(Instruction instr); + void luv(Instruction instr); + void lbv(Instruction instr); + void ldv(Instruction instr); + void lsv(Instruction instr); + void llv(Instruction instr); + void lrv(Instruction instr); + void lqv(Instruction instr); + void lfv(Instruction instr); + void lhv(Instruction instr); + void ltv(Instruction instr); + void lpv(Instruction instr); + void j(Instruction instr); + void jal(Instruction instr); + void jr(Instruction instr); + void jalr(Instruction instr); + void nor(Instruction instr); + void or_(Instruction instr); + void ori(Instruction instr); + void xor_(Instruction instr); + void xori(Instruction instr); + void sb(Instruction instr); + void sh(Instruction instr); + void sw(Instruction instr); + void swv(Instruction instr); + void sub(Instruction instr); + void sbv(Instruction instr); + void sdv(Instruction instr); + void stv(Instruction instr); + void sqv(Instruction instr); + void ssv(Instruction instr); + void suv(Instruction instr); + void slv(Instruction instr); + void shv(Instruction instr); + void sfv(Instruction instr); + void srv(Instruction instr); + void spv(Instruction instr); + void sllv(Instruction instr); + void srlv(Instruction instr); + void srav(Instruction instr); + void sll(Instruction instr); + void srl(Instruction instr); + void sra(Instruction instr); + void slt(Instruction instr); + void sltu(Instruction instr); + void slti(Instruction instr); + void sltiu(Instruction instr); + void vabs(Instruction instr); + void vadd(Instruction instr); + void vaddc(Instruction instr); + void vand(Instruction instr); + void vnand(Instruction instr); + void vch(Instruction instr); + void vcr(Instruction instr); + void vcl(Instruction instr); + void vmacf(Instruction instr); + void vmacu(Instruction instr); + void vmacq(Instruction instr); + void vmadh(Instruction instr); + void vmadl(Instruction instr); + void vmadm(Instruction instr); + void vmadn(Instruction instr); + void vmov(Instruction instr); + void vmulf(Instruction instr); + void vmulu(Instruction instr); + void vmulq(Instruction instr); + void vmudl(Instruction instr); + void vmudh(Instruction instr); + void vmudm(Instruction instr); + void vmudn(Instruction instr); + void vmrg(Instruction instr); + void vlt(Instruction instr); + void veq(Instruction instr); + void vne(Instruction instr); + void vge(Instruction instr); + void vrcp(Instruction instr); + void vrsq(Instruction instr); + void vrcpl(Instruction instr); + void vrsql(Instruction instr); + void vrndp(Instruction instr); + void vrndn(Instruction instr); + void vrcph(Instruction instr); + void vsar(Instruction instr); + void vsub(Instruction instr); + void vsubc(Instruction instr); + void vxor(Instruction instr); + void vnxor(Instruction instr); + void vor(Instruction instr); + void vnor(Instruction instr); + void vzero(Instruction instr); + void mfc0(const RDP &rdp, Instruction instr); + void mtc0(Instruction instr) const; + void mfc2(Instruction instr); + void mtc2(Instruction instr); template void DMA(); diff --git a/src/backend/core/interpreter/decode.cpp b/src/backend/core/interpreter/decode.cpp index c7be689d..b131f972 100644 --- a/src/backend/core/interpreter/decode.cpp +++ b/src/backend/core/interpreter/decode.cpp @@ -220,12 +220,12 @@ void Interpreter::regimm(const Instruction instr) { } } -void Interpreter::cop2Decode(const u32 instr) { +void Interpreter::cop2Decode(const Instruction instr) { if (!regs.cop0.status.cu2) { regs.cop0.FireException(ExceptionCode::CoprocessorUnusable, 2, regs.oldPC); return; } - switch (RS(instr)) { + switch (instr.rs()) { case 0x00: mfc2(instr); break; diff --git a/src/backend/core/jit/decode.cpp b/src/backend/core/jit/decode.cpp index 9bf0ea92..b55acf90 100644 --- a/src/backend/core/jit/decode.cpp +++ b/src/backend/core/jit/decode.cpp @@ -127,22 +127,22 @@ void JIT::special(const Instruction instr) { dsubu(instr); break; case Instruction::TGE: - trap(regs.Read(RS(instr)) >= regs.Read(RT(instr))); + trap(regs.Read(instr.rs()) >= regs.Read(instr.rt())); break; case Instruction::TGEU: - trap(regs.Read(RS(instr)) >= regs.Read(RT(instr))); + trap(regs.Read(instr.rs()) >= regs.Read(instr.rt())); break; case Instruction::TLT: - trap(regs.Read(RS(instr)) < regs.Read(RT(instr))); + trap(regs.Read(instr.rs()) < regs.Read(instr.rt())); break; case Instruction::TLTU: - trap(regs.Read(RS(instr)) < regs.Read(RT(instr))); + trap(regs.Read(instr.rs()) < regs.Read(instr.rt())); break; case Instruction::TEQ: - trap(regs.Read(RS(instr)) == regs.Read(RT(instr))); + trap(regs.Read(instr.rs()) == regs.Read(instr.rt())); break; case Instruction::TNE: - trap(regs.Read(RS(instr)) != regs.Read(RT(instr))); + trap(regs.Read(instr.rs()) != regs.Read(instr.rt())); break; case Instruction::DSLL: dsll(instr); @@ -184,22 +184,22 @@ void JIT::regimm(const Instruction instr) { bgezl(instr); break; case Instruction::TGEI: - trap(regs.Read(RS(instr)) >= static_cast(static_cast(instr))); + trap(regs.Read(instr.rs()) >= static_cast(static_cast(instr))); break; case Instruction::TGEIU: - trap(regs.Read(RS(instr)) >= static_cast(static_cast(static_cast(instr)))); + trap(regs.Read(instr.rs()) >= static_cast(static_cast(static_cast(instr)))); break; case Instruction::TLTI: - trap(regs.Read(RS(instr)) < static_cast(static_cast(instr))); + trap(regs.Read(instr.rs()) < static_cast(static_cast(instr))); break; case Instruction::TLTIU: - trap(regs.Read(RS(instr)) < static_cast(static_cast(static_cast(instr)))); + trap(regs.Read(instr.rs()) < static_cast(static_cast(static_cast(instr)))); break; case Instruction::TEQI: - trap(regs.Read(RS(instr)) == static_cast(static_cast(instr))); + trap(regs.Read(instr.rs()) == static_cast(static_cast(instr))); break; case Instruction::TNEI: - trap(regs.Read(RS(instr)) != static_cast(static_cast(instr))); + trap(regs.Read(instr.rs()) != static_cast(static_cast(instr))); break; case Instruction::BLTZAL: bltzal(instr); diff --git a/src/backend/core/jit/instructions.cpp b/src/backend/core/jit/instructions.cpp index 8a652a17..89140f83 100644 --- a/src/backend/core/jit/instructions.cpp +++ b/src/backend/core/jit/instructions.cpp @@ -949,8 +949,8 @@ void JIT::ld(const Instruction instr) { } void JIT::ldc1(const Instruction instr) { - if (regs.IsRegConstant(BASE(instr))) { - const u64 addr = static_cast(static_cast(instr)) + regs.Read(BASE(instr)); + if (regs.IsRegConstant(instr.base())) { + const u64 addr = static_cast(static_cast(instr)) + regs.Read(instr.base()); if (u32 physical; !regs.cop0.MapVAddr(Cop0::LOAD, addr, physical)) { // regs.cop0.HandleTLBException(addr); @@ -958,8 +958,8 @@ void JIT::ldc1(const Instruction instr) { panic("[JIT]: Unhandled TLBL exception in LD1!"); } else { const u64 data = mem.Read(physical); - regs.cop1.FGR_T(regs.cop0.status, FT(instr)) = data; - regs.cop1.fgrIsConstant[FT(instr)] = true; + regs.cop1.FGR_T(regs.cop0.status, instr.ft()) = data; + regs.cop1.fgrIsConstant[instr.ft()] = true; } } else { panic("[JIT]: Implement non constant LD1!"); diff --git a/src/backend/core/rsp/decode.cpp b/src/backend/core/rsp/decode.cpp index fa882876..b559f396 100644 --- a/src/backend/core/rsp/decode.cpp +++ b/src/backend/core/rsp/decode.cpp @@ -2,9 +2,9 @@ #include namespace n64 { -void RSP::special(const u32 instr) { +void RSP::special(const Instruction instr) { MI& mi = Core::GetMem().mmio.mi; - switch (const u8 mask = instr & 0x3f) { + switch (instr.cop_funct()) { case 0x00: if (instr != 0) { sll(instr); @@ -66,31 +66,31 @@ void RSP::special(const u32 instr) { sltu(instr); break; default: - panic("Unhandled RSP special instruction ({:06b})", mask); + panic("Unhandled RSP special instruction ({:06b})", instr.cop_funct()); } } -void RSP::regimm(const u32 instr) { - switch (const u8 mask = instr >> 16 & 0x1F) { +void RSP::regimm(const Instruction instr) { + switch (instr.cop_rt()) { case 0x00: - b(instr, gpr[RS(instr)] < 0); + b(instr, gpr[instr.rs()] < 0); break; case 0x01: - b(instr, gpr[RS(instr)] >= 0); + b(instr, gpr[instr.rs()] >= 0); break; case 0x10: - blink(instr, gpr[RS(instr)] < 0); + blink(instr, gpr[instr.rs()] < 0); break; case 0x11: - blink(instr, gpr[RS(instr)] >= 0); + blink(instr, gpr[instr.rs()] >= 0); break; default: - panic("Unhandled RSP regimm instruction ({:05b})", mask); + panic("Unhandled RSP regimm instruction ({:05b})", instr.cop_rt()); } } -void RSP::lwc2(const u32 instr) { - switch (const u8 mask = instr >> 11 & 0x1F) { +void RSP::lwc2(const Instruction instr) { + switch (instr.rd()) { case 0x00: lbv(instr); break; @@ -127,12 +127,12 @@ void RSP::lwc2(const u32 instr) { ltv(instr); break; default: - panic("Unhandled RSP LWC2 {:05b}", mask); + panic("Unhandled RSP LWC2 {:05b}", instr.rd()); } } -void RSP::swc2(const u32 instr) { - switch (const u8 mask = instr >> 11 & 0x1F) { +void RSP::swc2(const Instruction instr) { + switch (instr.rd()) { case 0x00: sbv(instr); break; @@ -170,18 +170,17 @@ void RSP::swc2(const u32 instr) { stv(instr); break; default: - panic("Unhandled RSP SWC2 {:05b}", mask); + panic("Unhandled RSP SWC2 {:05b}", instr.rd()); } } -void RSP::cop2(const u32 instr) { - const u8 mask_sub = instr >> 21 & 0x1F; - switch (const u8 mask = instr & 0x3F) { +void RSP::cop2(const Instruction instr) { + switch (instr.cop_funct()) { case 0x00: if (instr >> 25 & 1) { vmulf(instr); } else { - switch (mask_sub) { + switch (instr.cop_rs()) { case 0x00: mfc2(instr); break; @@ -195,7 +194,7 @@ void RSP::cop2(const u32 instr) { ctc2(instr); break; default: - panic("Unhandled RSP COP2 sub ({:05b})", mask_sub); + panic("Unhandled RSP COP2 sub ({:05b})", instr.cop_rs()); } } break; @@ -340,13 +339,13 @@ void RSP::cop2(const u32 instr) { case 0x3F: break; default: - panic("Unhandled RSP COP2 ({:06b})", mask); + panic("Unhandled RSP COP2 ({:06b})", instr.cop_funct()); } } -void RSP::cop0(const u32 instr) { +void RSP::cop0(const Instruction instr) { if ((instr & 0x7FF) == 0) { - switch (const u8 mask = instr >> 21 & 0x1F) { + switch (instr.cop_rs()) { case 0x00: mfc0(Core::GetMem().mmio.rdp, instr); break; @@ -354,18 +353,18 @@ void RSP::cop0(const u32 instr) { mtc0(instr); break; default: - panic("Unhandled RSP COP0 ({:05b})", mask); + panic("Unhandled RSP COP0 ({:05b})", instr.cop_rs()); } } else { - panic("RSP COP0 unknown {:08X}", instr); + panic("RSP COP0 unknown {:08X}", u32(instr)); } } -void RSP::Exec(const u32 instr) { +void RSP::Exec(const Instruction instr) { Mem& mem = Core::GetMem(); MMIO &mmio = mem.mmio; MI &mi = mmio.mi; - switch (const u8 mask = instr >> 26 & 0x3F) { + switch (instr.opcode()) { case 0x00: special(instr); break; @@ -379,16 +378,16 @@ void RSP::Exec(const u32 instr) { jal(instr); break; case 0x04: - b(instr, gpr[RT(instr)] == gpr[RS(instr)]); + b(instr, gpr[instr.rt()] == gpr[instr.rs()]); break; case 0x05: - b(instr, gpr[RT(instr)] != gpr[RS(instr)]); + b(instr, gpr[instr.rt()] != gpr[instr.rs()]); break; case 0x06: - b(instr, gpr[RS(instr)] <= 0); + b(instr, gpr[instr.rs()] <= 0); break; case 0x07: - b(instr, gpr[RS(instr)] > 0); + b(instr, gpr[instr.rs()] > 0); break; case 0x08: case 0x09: @@ -451,7 +450,7 @@ void RSP::Exec(const u32 instr) { break; default: mem.DumpIMEM(); - panic("Unhandled RSP instruction ({:06b}, {:04X})", mask, oldPC); + panic("Unhandled RSP instruction ({:06b}, {:04X})", instr.opcode(), oldPC); } } } // namespace n64 diff --git a/src/backend/core/rsp/instructions.cpp b/src/backend/core/rsp/instructions.cpp index 185faed3..da5af5e3 100644 --- a/src/backend/core/rsp/instructions.cpp +++ b/src/backend/core/rsp/instructions.cpp @@ -177,22 +177,22 @@ void RSP::SetVTE(const VPR &vt, u8 e) { } #endif -void RSP::add(const u32 instr) { gpr[RD(instr)] = gpr[RS(instr)] + gpr[RT(instr)]; } +void RSP::add(const Instruction instr) { gpr[instr.rd()] = gpr[instr.rs()] + gpr[instr.rt()]; } -void RSP::addi(const u32 instr) { - const s32 op1 = gpr[RS(instr)]; +void RSP::addi(const Instruction instr) { + const s32 op1 = gpr[instr.rs()]; const s16 op2 = instr; const s32 result = op1 + op2; - gpr[RT(instr)] = result; + gpr[instr.rt()] = result; } -void RSP::and_(const u32 instr) { gpr[RD(instr)] = gpr[RT(instr)] & gpr[RS(instr)]; } +void RSP::and_(const Instruction instr) { gpr[instr.rd()] = gpr[instr.rt()] & gpr[instr.rs()]; } -void RSP::andi(const u32 instr) { gpr[RT(instr)] = gpr[RS(instr)] & (u16)instr; } +void RSP::andi(const Instruction instr) { gpr[instr.rt()] = gpr[instr.rs()] & (u16)instr; } -void RSP::cfc2(const u32 instr) { +void RSP::cfc2(const Instruction instr) { s16 value = 0; - switch (RD(instr) & 3) { + switch (instr.rd() & 3) { case 0: value = GetVCO(); break; @@ -204,12 +204,12 @@ void RSP::cfc2(const u32 instr) { break; } - gpr[RT(instr)] = value; + gpr[instr.rt()] = value; } -void RSP::ctc2(const u32 instr) { - const u16 value = gpr[RT(instr)]; - switch (RD(instr) & 3) { +void RSP::ctc2(const Instruction instr) { + const u16 value = gpr[instr.rt()]; + switch (instr.rd() & 3) { case 0: for (int i = 0; i < 8; i++) { vco.h.element[ELEMENT_INDEX(i)] = ((value >> (i + 8)) & 1) == 1 ? 0xFFFF : 0; @@ -231,61 +231,61 @@ void RSP::ctc2(const u32 instr) { } } -void RSP::b(const u32 instr, const bool cond) { +void RSP::b(const Instruction instr, const bool cond) { const u32 address = ((instr & 0xFFFF) << 2) + pc; branch(address, cond); } -void RSP::blink(const u32 instr, const bool cond) { +void RSP::blink(const Instruction instr, const bool cond) { b(instr, cond); gpr[31] = pc + 4; } -void RSP::lb(const u32 instr) { - const u32 address = gpr[BASE(instr)] + (s16)instr; - gpr[RT(instr)] = (s32)(s8)ReadByte(address); +void RSP::lb(const Instruction instr) { + const u32 address = gpr[instr.base()] + (s16)instr; + gpr[instr.rt()] = (s32)(s8)ReadByte(address); } -void RSP::lh(const u32 instr) { - const u32 address = gpr[BASE(instr)] + (s16)instr; - gpr[RT(instr)] = (s32)(s16)ReadHalf(address); +void RSP::lh(const Instruction instr) { + const u32 address = gpr[instr.base()] + (s16)instr; + gpr[instr.rt()] = (s32)(s16)ReadHalf(address); } -void RSP::lw(const u32 instr) { - const u32 address = gpr[BASE(instr)] + (s16)instr; - gpr[RT(instr)] = ReadWord(address); +void RSP::lw(const Instruction instr) { + const u32 address = gpr[instr.base()] + (s16)instr; + gpr[instr.rt()] = ReadWord(address); } -void RSP::lbu(const u32 instr) { - const u32 address = gpr[BASE(instr)] + (s16)instr; - gpr[RT(instr)] = ReadByte(address); +void RSP::lbu(const Instruction instr) { + const u32 address = gpr[instr.base()] + (s16)instr; + gpr[instr.rt()] = ReadByte(address); } -void RSP::lhu(const u32 instr) { - const u32 address = gpr[BASE(instr)] + (s16)instr; - gpr[RT(instr)] = ReadHalf(address); +void RSP::lhu(const Instruction instr) { + const u32 address = gpr[instr.base()] + (s16)instr; + gpr[instr.rt()] = ReadHalf(address); } -void RSP::lui(const u32 instr) { +void RSP::lui(const Instruction instr) { u32 imm = ((u16)instr) << 16; - gpr[RT(instr)] = imm; + gpr[instr.rt()] = imm; } #define OFFSET(x) ((x) & 0x7F) -void RSP::lqv(const u32 instr) { - int e = E1(instr); - u32 addr = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 4); +void RSP::lqv(const Instruction instr) { + int e = instr.e1(); + u32 addr = gpr[instr.base()] + SignExt7bit(OFFSET(instr), 4); u32 end = ((addr & ~15) + 15); for (int i = 0; addr + i <= end && i + e < 16; i++) { - vpr[VT(instr)].byte[BYTE_INDEX(i + e)] = ReadByte(addr + i); + vpr[instr.vt()].byte[BYTE_INDEX(i + e)] = ReadByte(addr + i); } } -void RSP::lpv(const u32 instr) { - const int e = E1(instr); - u32 addr = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 3); +void RSP::lpv(const Instruction instr) { + const int e = instr.e1(); + u32 addr = gpr[instr.base()] + SignExt7bit(OFFSET(instr), 3); const int addrOffset = addr & 7; addr &= ~7; @@ -295,14 +295,14 @@ void RSP::lpv(const u32 instr) { u16 value = ReadByte(addr + elemOffset); value <<= 8; - vpr[VT(instr)].element[ELEMENT_INDEX(elem)] = value; + vpr[instr.vt()].element[ELEMENT_INDEX(elem)] = value; } } -void RSP::luv(const u32 instr) { - u32 addr = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 3); +void RSP::luv(const Instruction instr) { + u32 addr = gpr[instr.base()] + SignExt7bit(OFFSET(instr), 3); - const int e = E1(instr); + const int e = instr.e1(); const int addrOffset = addr & 7; addr &= ~7; @@ -312,54 +312,54 @@ void RSP::luv(const u32 instr) { u16 value = ReadByte(addr + elemOffset); value <<= 7; - vpr[VT(instr)].element[ELEMENT_INDEX(elem)] = value; + vpr[instr.vt()].element[ELEMENT_INDEX(elem)] = value; } } -void RSP::suv(const u32 instr) { - u32 addr = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 3); +void RSP::suv(const Instruction instr) { + u32 addr = gpr[instr.base()] + SignExt7bit(OFFSET(instr), 3); - const int start = E1(instr); + const int start = instr.e1(); const int end = start + 8; for (int offset = start; offset < end; offset++) { if ((offset & 15) < 8) { - WriteByte(addr++, vpr[VT(instr)].element[ELEMENT_INDEX(offset & 7)] >> 7); + WriteByte(addr++, vpr[instr.vt()].element[ELEMENT_INDEX(offset & 7)] >> 7); } else { - WriteByte(addr++, vpr[VT(instr)].byte[BYTE_INDEX((offset & 7) << 1)]); + WriteByte(addr++, vpr[instr.vt()].byte[BYTE_INDEX((offset & 7) << 1)]); } } } -void RSP::ldv(const u32 instr) { - const int e = E1(instr); - u32 addr = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 3); +void RSP::ldv(const Instruction instr) { + const int e = instr.e1(); + u32 addr = gpr[instr.base()] + SignExt7bit(OFFSET(instr), 3); const u32 end = e + 8 > 16 ? 16 : e + 8; for (int i = e; i < end; i++) { - vpr[VT(instr)].byte[BYTE_INDEX(i)] = ReadByte(addr); + vpr[instr.vt()].byte[BYTE_INDEX(i)] = ReadByte(addr); addr++; } } -void RSP::lsv(const u32 instr) { - const u8 e = E1(instr); - const u32 addr = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 1); +void RSP::lsv(const Instruction instr) { + const u8 e = instr.e1(); + const u32 addr = gpr[instr.base()] + SignExt7bit(OFFSET(instr), 1); const u16 val = ReadHalf(addr); - vpr[VT(instr)].byte[BYTE_INDEX(e)] = val >> 8; + vpr[instr.vt()].byte[BYTE_INDEX(e)] = val >> 8; if (e < 15) { - vpr[VT(instr)].byte[BYTE_INDEX(e + 1)] = val; + vpr[instr.vt()].byte[BYTE_INDEX(e + 1)] = val; } } -void RSP::lbv(const u32 instr) { - const u32 address = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 0); - vpr[VT(instr)].byte[BYTE_INDEX(E1(instr))] = ReadByte(address); +void RSP::lbv(const Instruction instr) { + const u32 address = gpr[instr.base()] + SignExt7bit(OFFSET(instr), 0); + vpr[instr.vt()].byte[BYTE_INDEX(instr.e1())] = ReadByte(address); } -void RSP::llv(const u32 instr) { - const int e = E1(instr); - const u32 addr = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 2); +void RSP::llv(const Instruction instr) { + const int e = instr.e1(); + const u32 addr = gpr[instr.base()] + SignExt7bit(OFFSET(instr), 2); for (int i = 0; i < 4; i++) { const int elem = i + e; @@ -367,125 +367,125 @@ void RSP::llv(const u32 instr) { break; } - vpr[VT(instr)].byte[BYTE_INDEX(elem)] = ReadByte(addr + i); + vpr[instr.vt()].byte[BYTE_INDEX(elem)] = ReadByte(addr + i); } } -void RSP::j(const u32 instr) { +void RSP::j(const Instruction instr) { const u32 target = (instr & 0x3ffffff) << 2; nextPC = target; } -void RSP::jal(const u32 instr) { +void RSP::jal(const Instruction instr) { j(instr); gpr[31] = pc + 4; } -void RSP::jr(const u32 instr) { nextPC = gpr[RS(instr)]; } +void RSP::jr(const Instruction instr) { nextPC = gpr[instr.rs()]; } -void RSP::jalr(const u32 instr) { +void RSP::jalr(const Instruction instr) { jr(instr); - gpr[RD(instr)] = pc + 4; + gpr[instr.rd()] = pc + 4; } -void RSP::nor(const u32 instr) { gpr[RD(instr)] = ~(gpr[RT(instr)] | gpr[RS(instr)]); } +void RSP::nor(const Instruction instr) { gpr[instr.rd()] = ~(gpr[instr.rt()] | gpr[instr.rs()]); } -void RSP::ori(const u32 instr) { - const s32 op1 = gpr[RS(instr)]; +void RSP::ori(const Instruction instr) { + const s32 op1 = gpr[instr.rs()]; const u32 op2 = instr & 0xffff; const s32 result = op1 | op2; - gpr[RT(instr)] = result; + gpr[instr.rt()] = result; } -void RSP::xori(const u32 instr) { - const s32 op1 = gpr[RS(instr)]; +void RSP::xori(const Instruction instr) { + const s32 op1 = gpr[instr.rs()]; const u32 op2 = instr & 0xffff; const s32 result = op1 ^ op2; - gpr[RT(instr)] = result; + gpr[instr.rt()] = result; } -void RSP::or_(const u32 instr) { gpr[RD(instr)] = gpr[RT(instr)] | gpr[RS(instr)]; } +void RSP::or_(const Instruction instr) { gpr[instr.rd()] = gpr[instr.rt()] | gpr[instr.rs()]; } -void RSP::xor_(const u32 instr) { gpr[RD(instr)] = gpr[RT(instr)] ^ gpr[RS(instr)]; } +void RSP::xor_(const Instruction instr) { gpr[instr.rd()] = gpr[instr.rt()] ^ gpr[instr.rs()]; } -void RSP::sb(const u32 instr) { - const u32 address = gpr[BASE(instr)] + (s16)instr; - WriteByte(address, gpr[RT(instr)]); +void RSP::sb(const Instruction instr) { + const u32 address = gpr[instr.base()] + (s16)instr; + WriteByte(address, gpr[instr.rt()]); } -void RSP::sh(const u32 instr) { +void RSP::sh(const Instruction instr) { const s16 imm = s16(instr); - const u32 address = gpr[RS(instr)] + imm; - WriteHalf(address, gpr[RT(instr)]); + const u32 address = gpr[instr.rs()] + imm; + WriteHalf(address, gpr[instr.rt()]); } -void RSP::sw(const u32 instr) { - const u32 address = gpr[BASE(instr)] + (s16)instr; - WriteWord(address, gpr[RT(instr)]); +void RSP::sw(const Instruction instr) { + const u32 address = gpr[instr.base()] + (s16)instr; + WriteWord(address, gpr[instr.rt()]); } -void RSP::swv(const u32 instr) { - u32 address = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 4); +void RSP::swv(const Instruction instr) { + u32 address = gpr[instr.base()] + SignExt7bit(OFFSET(instr), 4); int base = address & 7; address &= ~7; - for (int i = E1(instr); i < E1(instr) + 16; i++) { - WriteByte(address + (base & 15), vpr[VT(instr)].byte[BYTE_INDEX(i & 15)]); + for (int i = instr.e1(); i < instr.e1() + 16; i++) { + WriteByte(address + (base & 15), vpr[instr.vt()].byte[BYTE_INDEX(i & 15)]); base++; } } -void RSP::sub(const u32 instr) { gpr[RD(instr)] = gpr[RS(instr)] - gpr[RT(instr)]; } +void RSP::sub(const Instruction instr) { gpr[instr.rd()] = gpr[instr.rs()] - gpr[instr.rt()]; } -void RSP::sqv(const u32 instr) { - const int e = E1(instr); - const u32 addr = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 4); +void RSP::sqv(const Instruction instr) { + const int e = instr.e1(); + const u32 addr = gpr[instr.base()] + SignExt7bit(OFFSET(instr), 4); const u32 end = ((addr & ~15) + 15); for (int i = 0; addr + i <= end; i++) { - WriteByte(addr + i, vpr[VT(instr)].byte[BYTE_INDEX((i + e) & 15)]); + WriteByte(addr + i, vpr[instr.vt()].byte[BYTE_INDEX((i + e) & 15)]); } } -void RSP::spv(const u32 instr) { - const int e = E1(instr); - u32 addr = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 3); +void RSP::spv(const Instruction instr) { + const int e = instr.e1(); + u32 addr = gpr[instr.base()] + SignExt7bit(OFFSET(instr), 3); const int start = e; const int end = start + 8; for (int offset = start; offset < end; offset++) { if ((offset & 15) < 8) { - WriteByte(addr++, vpr[VT(instr)].byte[BYTE_INDEX((offset & 7) << 1)]); + WriteByte(addr++, vpr[instr.vt()].byte[BYTE_INDEX((offset & 7) << 1)]); } else { - WriteByte(addr++, vpr[VT(instr)].element[ELEMENT_INDEX(offset & 7)] >> 7); + WriteByte(addr++, vpr[instr.vt()].element[ELEMENT_INDEX(offset & 7)] >> 7); } } } -void RSP::srv(const u32 instr) { - u32 address = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 4); - const int start = E1(instr); +void RSP::srv(const Instruction instr) { + u32 address = gpr[instr.base()] + SignExt7bit(OFFSET(instr), 4); + const int start = instr.e1(); const int end = start + (address & 15); const int base = 16 - (address & 15); address &= ~15; for (int i = start; i < end; i++) { - WriteByte(address++, vpr[VT(instr)].byte[BYTE_INDEX((i + base) & 0xF)]); + WriteByte(address++, vpr[instr.vt()].byte[BYTE_INDEX((i + base) & 0xF)]); } } -void RSP::shv(const u32 instr) { - u32 address = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 4); +void RSP::shv(const Instruction instr) { + u32 address = gpr[instr.base()] + SignExt7bit(OFFSET(instr), 4); const u32 in_addr_offset = address & 0x7; address &= ~0x7; - const int e = E1(instr); + const int e = instr.e1(); for (int i = 0; i < 8; i++) { const int byte_index = (i * 2) + e; - u16 val = vpr[VT(instr)].byte[BYTE_INDEX(byte_index & 15)] << 1; - val |= vpr[VT(instr)].byte[BYTE_INDEX((byte_index + 1) & 15)] >> 7; + u16 val = vpr[instr.vt()].byte[BYTE_INDEX(byte_index & 15)] << 1; + val |= vpr[instr.vt()].byte[BYTE_INDEX((byte_index + 1) & 15)] >> 7; u8 b = val & 0xFF; const int ofs = in_addr_offset + (i * 2); @@ -493,26 +493,26 @@ void RSP::shv(const u32 instr) { } } -void RSP::lhv(const u32 instr) { - u32 address = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 4); +void RSP::lhv(const Instruction instr) { + u32 address = gpr[instr.base()] + SignExt7bit(OFFSET(instr), 4); const u32 in_addr_offset = address & 0x7; address &= ~0x7; - const int e = E1(instr); + const int e = instr.e1(); for (int i = 0; i < 8; i++) { const int ofs = ((16 - e) + (i * 2) + in_addr_offset) & 0xF; u16 val = ReadByte(address + ofs); val <<= 7; - vpr[VT(instr)].element[ELEMENT_INDEX(i)] = val; + vpr[instr.vt()].element[ELEMENT_INDEX(i)] = val; } } -void RSP::lfv(const u32 instr) { - VPR &vt = vpr[VT(instr)]; - const int start = E1(instr); - u32 address = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 4); +void RSP::lfv(const Instruction instr) { + VPR &vt = vpr[instr.vt()]; + const int start = instr.e1(); + u32 address = gpr[instr.base()] + SignExt7bit(OFFSET(instr), 4); const u32 base = (address & 7) - start; address &= ~7; @@ -530,23 +530,23 @@ void RSP::lfv(const u32 instr) { } } -void RSP::lrv(const u32 instr) { - u32 address = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 4); - const int e = E1(instr); +void RSP::lrv(const Instruction instr) { + u32 address = gpr[instr.base()] + SignExt7bit(OFFSET(instr), 4); + const int e = instr.e1(); const int start = 16 - ((address & 15) - e); address &= ~15; for (int i = start; i < 16; i++) { - vpr[VT(instr)].byte[BYTE_INDEX(i & 0xF)] = ReadByte(address++); + vpr[instr.vt()].byte[BYTE_INDEX(i & 0xF)] = ReadByte(address++); } } -void RSP::sfv(const u32 instr) { - const VPR &vt = vpr[VT(instr)]; - u32 address = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 4); +void RSP::sfv(const Instruction instr) { + const VPR &vt = vpr[instr.vt()]; + u32 address = gpr[instr.base()] + SignExt7bit(OFFSET(instr), 4); const int base = address & 7; address &= ~7; - const int e = E1(instr); + const int e = instr.e1(); u8 values[4] = {0, 0, 0, 0}; @@ -603,54 +603,54 @@ void RSP::sfv(const u32 instr) { } } -void RSP::sbv(const u32 instr) { - const int e = E1(instr); - const u32 addr = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 0); +void RSP::sbv(const Instruction instr) { + const int e = instr.e1(); + const u32 addr = gpr[instr.base()] + SignExt7bit(OFFSET(instr), 0); - WriteByte(addr, vpr[VT(instr)].byte[BYTE_INDEX(e & 0xF)]); + WriteByte(addr, vpr[instr.vt()].byte[BYTE_INDEX(e & 0xF)]); } -void RSP::sdv(const u32 instr) { - const int e = E1(instr); - const u32 addr = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 3); +void RSP::sdv(const Instruction instr) { + const int e = instr.e1(); + const u32 addr = gpr[instr.base()] + SignExt7bit(OFFSET(instr), 3); for (int i = 0; i < 8; i++) { - WriteByte(addr + i, vpr[VT(instr)].byte[BYTE_INDEX((i + e) & 0xF)]); + WriteByte(addr + i, vpr[instr.vt()].byte[BYTE_INDEX((i + e) & 0xF)]); } } -void RSP::ssv(const u32 instr) { - const int e = E1(instr); - const u32 addr = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 1); +void RSP::ssv(const Instruction instr) { + const int e = instr.e1(); + const u32 addr = gpr[instr.base()] + SignExt7bit(OFFSET(instr), 1); - const u8 hi = vpr[VT(instr)].byte[BYTE_INDEX(e & 15)]; - const u8 lo = vpr[VT(instr)].byte[BYTE_INDEX((e + 1) & 15)]; + const u8 hi = vpr[instr.vt()].byte[BYTE_INDEX(e & 15)]; + const u8 lo = vpr[instr.vt()].byte[BYTE_INDEX((e + 1) & 15)]; const u16 val = (u16)hi << 8 | lo; WriteHalf(addr, val); } -void RSP::slv(const u32 instr) { - const int e = E1(instr); - const u32 addr = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 2); +void RSP::slv(const Instruction instr) { + const int e = instr.e1(); + const u32 addr = gpr[instr.base()] + SignExt7bit(OFFSET(instr), 2); for (int i = 0; i < 4; i++) { - WriteByte(addr + i, vpr[VT(instr)].byte[BYTE_INDEX((i + e) & 0xF)]); + WriteByte(addr + i, vpr[instr.vt()].byte[BYTE_INDEX((i + e) & 0xF)]); } } -void RSP::stv(const u32 instr) { - u32 base = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 4); +void RSP::stv(const Instruction instr) { + u32 base = gpr[instr.base()] + SignExt7bit(OFFSET(instr), 4); const u32 addrOffset = base & 0x7; base &= ~0x7; - const u8 e = E1(instr) >> 1; + const u8 e = instr.e1() >> 1; for (int i = 0; i < 8; i++) { const u32 address = base; const u32 offset = (i << 1) + addrOffset; - const int reg = (VT(instr) & 0x18) | ((i + e) & 0x7); + const int reg = (instr.vt() & 0x18) | ((i + e) & 0x7); const u16 val = vpr[reg].element[ELEMENT_INDEX(i & 0x7)]; const u16 hi = (val >> 8) & 0xFF; @@ -661,11 +661,11 @@ void RSP::stv(const u32 instr) { } } -void RSP::ltv(const u32 instr) { - u32 base = gpr[BASE(instr)] + SignExt7bit(OFFSET(instr), 4); +void RSP::ltv(const Instruction instr) { + u32 base = gpr[instr.base()] + SignExt7bit(OFFSET(instr), 4); base &= ~0x7; - const u8 e = E1(instr); + const u8 e = instr.e1(); for (int i = 0; i < 8; i++) { const u32 address = base; @@ -674,60 +674,60 @@ void RSP::ltv(const u32 instr) { const u16 hi = ReadByte(address + (offset & 0xF)); const u16 lo = ReadByte(address + ((offset + 1) & 0xF)); - const int reg = (VT(instr) & 0x18) | ((i + (e >> 1)) & 0x7); + const int reg = (instr.vt() & 0x18) | ((i + (e >> 1)) & 0x7); vpr[reg].element[ELEMENT_INDEX(i & 0x7)] = (hi << 8) | lo; } } -void RSP::sllv(const u32 instr) { - const u8 sa = (gpr[RS(instr)]) & 0x1F; - const u32 rt = gpr[RT(instr)]; +void RSP::sllv(const Instruction instr) { + const u8 sa = (gpr[instr.rs()]) & 0x1F; + const u32 rt = gpr[instr.rt()]; const u32 result = rt << sa; - gpr[RD(instr)] = result; + gpr[instr.rd()] = result; } -void RSP::srlv(const u32 instr) { - const u8 sa = (gpr[RS(instr)]) & 0x1F; - const u32 rt = gpr[RT(instr)]; +void RSP::srlv(const Instruction instr) { + const u8 sa = (gpr[instr.rs()]) & 0x1F; + const u32 rt = gpr[instr.rt()]; const u32 result = rt >> sa; - gpr[RD(instr)] = result; + gpr[instr.rd()] = result; } -void RSP::srav(const u32 instr) { - const u8 sa = gpr[RS(instr)] & 0x1F; - const s32 rt = gpr[RT(instr)]; +void RSP::srav(const Instruction instr) { + const u8 sa = gpr[instr.rs()] & 0x1F; + const s32 rt = gpr[instr.rt()]; const s32 result = rt >> sa; - gpr[RD(instr)] = result; + gpr[instr.rd()] = result; } -void RSP::sll(const u32 instr) { +void RSP::sll(const Instruction instr) { const u8 sa = (instr >> 6) & 0x1f; - gpr[RD(instr)] = (u32)gpr[RT(instr)] << sa; + gpr[instr.rd()] = (u32)gpr[instr.rt()] << sa; } -void RSP::srl(const u32 instr) { +void RSP::srl(const Instruction instr) { const u8 sa = (instr >> 6) & 0x1f; - gpr[RD(instr)] = (u32)gpr[RT(instr)] >> sa; + gpr[instr.rd()] = (u32)gpr[instr.rt()] >> sa; } -void RSP::sra(const u32 instr) { +void RSP::sra(const Instruction instr) { const u8 sa = (instr >> 6) & 0x1f; - gpr[RD(instr)] = gpr[RT(instr)] >> sa; + gpr[instr.rd()] = gpr[instr.rt()] >> sa; } -void RSP::slt(const u32 instr) { gpr[RD(instr)] = gpr[RS(instr)] < gpr[RT(instr)]; } +void RSP::slt(const Instruction instr) { gpr[instr.rd()] = gpr[instr.rs()] < gpr[instr.rt()]; } -void RSP::sltu(const u32 instr) { gpr[RD(instr)] = (u32)gpr[RS(instr)] < (u32)gpr[RT(instr)]; } +void RSP::sltu(const Instruction instr) { gpr[instr.rd()] = (u32)gpr[instr.rs()] < (u32)gpr[instr.rt()]; } -void RSP::slti(const u32 instr) { +void RSP::slti(const Instruction instr) { const s32 imm = (s16)instr; - gpr[RT(instr)] = gpr[RS(instr)] < imm; + gpr[instr.rt()] = gpr[instr.rs()] < imm; } -void RSP::sltiu(const u32 instr) { +void RSP::sltiu(const Instruction instr) { const s32 imm = (s16)instr; - gpr[RT(instr)] = (u32)gpr[RS(instr)] < imm; + gpr[instr.rt()] = (u32)gpr[instr.rs()] < imm; } FORCE_INLINE s16 signedClamp(const s64 val) { @@ -747,10 +747,10 @@ FORCE_INLINE u16 unsignedClamp(const s64 val) { } #ifdef SIMD_SUPPORT -void RSP::vabs(const u32 instr) { - const VPR &vs = vpr[VS(instr)]; - VPR &vd = vpr[VD(instr)]; - SetVTE(vpr[VT(instr)], E2(instr)); +void RSP::vabs(const Instruction instr) { + const VPR &vs = vpr[instr.vs()]; + VPR &vd = vpr[instr.vd()]; + SetVTE(vpr[instr.vt()], instr.e2()); const m128i isZero = _mm_cmpeq_epi16(vs.single, m128i{}); const m128i isNeg = _mm_srai_epi16(vs.single, 15); @@ -760,10 +760,10 @@ void RSP::vabs(const u32 instr) { vd.single = _mm_subs_epi16(temp, isNeg); } #else -void RSP::vabs(const u32 instr) { - VPR &vs = vpr[VS(instr)]; - VPR &vd = vpr[VD(instr)]; - SetVTE(vpr[VT(instr)], E2(instr)); +void RSP::vabs(const Instruction instr) { + VPR &vs = vpr[instr.vs()]; + VPR &vd = vpr[instr.vd()]; + SetVTE(vpr[instr.vt()], instr.e2()); for (int i = 0; i < 8; i++) { if (vs.selement[i] < 0) { @@ -785,10 +785,10 @@ void RSP::vabs(const u32 instr) { } #endif -void RSP::vadd(const u32 instr) { - const VPR &vs = vpr[VS(instr)]; - VPR &vd = vpr[VD(instr)]; - SetVTE(vpr[VT(instr)], E2(instr)); +void RSP::vadd(const Instruction instr) { + const VPR &vs = vpr[instr.vs()]; + VPR &vd = vpr[instr.vd()]; + SetVTE(vpr[instr.vt()], instr.e2()); for (int i = 0; i < 8; i++) { const s32 result = vs.selement[i] + vte.selement[i] + (vco.l.selement[i] != 0); @@ -799,10 +799,10 @@ void RSP::vadd(const u32 instr) { } } -void RSP::vaddc(const u32 instr) { - const VPR &vs = vpr[VS(instr)]; - VPR &vd = vpr[VD(instr)]; - SetVTE(vpr[VT(instr)], E2(instr)); +void RSP::vaddc(const Instruction instr) { + const VPR &vs = vpr[instr.vs()]; + VPR &vd = vpr[instr.vd()]; + SetVTE(vpr[instr.vt()], instr.e2()); for (int i = 0; i < 8; i++) { const u32 result = vs.element[i] + vte.element[i]; @@ -813,11 +813,11 @@ void RSP::vaddc(const u32 instr) { } } -void RSP::vch(const u32 instr) { - const int e = E2(instr); - const VPR &vs = vpr[VS(instr)]; - VPR &vd = vpr[VD(instr)]; - SetVTE(vpr[VT(instr)], e); +void RSP::vch(const Instruction instr) { + const int e = instr.e2(); + const VPR &vs = vpr[instr.vs()]; + VPR &vd = vpr[instr.vd()]; + SetVTE(vpr[instr.vt()], e); for (int i = 0; i < 8; i++) { s16 vsElem = vs.selement[i]; @@ -845,11 +845,11 @@ void RSP::vch(const u32 instr) { } } -void RSP::vcr(const u32 instr) { - const int e = E2(instr); - const VPR &vs = vpr[VS(instr)]; - VPR &vd = vpr[VD(instr)]; - SetVTE(vpr[VT(instr)], e); +void RSP::vcr(const Instruction instr) { + const int e = instr.e2(); + const VPR &vs = vpr[instr.vs()]; + VPR &vd = vpr[instr.vd()]; + SetVTE(vpr[instr.vt()], e); for (int i = 0; i < 8; i++) { u16 vsE = vs.element[i]; @@ -877,11 +877,11 @@ void RSP::vcr(const u32 instr) { } } -void RSP::vcl(const u32 instr) { - const int e = E2(instr); - const VPR &vs = vpr[VS(instr)]; - VPR &vd = vpr[VD(instr)]; - SetVTE(vpr[VT(instr)], e); +void RSP::vcl(const Instruction instr) { + const int e = instr.e2(); + const VPR &vs = vpr[instr.vs()]; + VPR &vd = vpr[instr.vd()]; + SetVTE(vpr[instr.vt()], e); for (int i = 0; i < 8; i++) { u16 vs_element = vs.element[i]; @@ -911,10 +911,10 @@ void RSP::vcl(const u32 instr) { vd.element[i] = acc.l.element[i]; } } -void RSP::vmov(const u32 instr) { - const u8 e = E2(instr), vs = VS(instr) & 7; - VPR &vd = vpr[VD(instr)]; - SetVTE(vpr[VT(instr)], e); +void RSP::vmov(const Instruction instr) { + const u8 e = instr.e2(), vs = instr.vs() & 7; + VPR &vd = vpr[instr.vd()]; + SetVTE(vpr[instr.vt()], e); u8 se; switch (e) { @@ -956,11 +956,11 @@ FORCE_INLINE bool IsSignExtension(const s16 hi, const s16 lo) { return false; } -void RSP::vmulf(const u32 instr) { - const int e = E2(instr); - const VPR &vs = vpr[VS(instr)]; - VPR &vd = vpr[VD(instr)]; - SetVTE(vpr[VT(instr)], e); +void RSP::vmulf(const Instruction instr) { + const int e = instr.e2(); + const VPR &vs = vpr[instr.vs()]; + VPR &vd = vpr[instr.vd()]; + SetVTE(vpr[instr.vt()], e); for (int i = 0; i < 8; i++) { const s16 op1 = vte.element[i]; @@ -977,10 +977,10 @@ void RSP::vmulf(const u32 instr) { } } -void RSP::vmulq(const u32 instr) { - const VPR &vs = vpr[VS(instr)]; - SetVTE(vpr[VT(instr)], E2(instr)); - VPR &vd = vpr[VD(instr)]; +void RSP::vmulq(const Instruction instr) { + const VPR &vs = vpr[instr.vs()]; + SetVTE(vpr[instr.vt()], instr.e2()); + VPR &vd = vpr[instr.vd()]; for (int i = 0; i < 8; i++) { const bool neg = vte.selement[i] < 0 && vs.selement[i] >= 0 || vs.selement[i] < 0 && vte.selement[i] >= 0; @@ -993,11 +993,11 @@ void RSP::vmulq(const u32 instr) { } } -void RSP::vmulu(const u32 instr) { - const int e = E2(instr); - const VPR &vs = vpr[VS(instr)]; - VPR &vd = vpr[VD(instr)]; - SetVTE(vpr[VT(instr)], e); +void RSP::vmulu(const Instruction instr) { + const int e = instr.e2(); + const VPR &vs = vpr[instr.vs()]; + VPR &vd = vpr[instr.vd()]; + SetVTE(vpr[instr.vt()], e); for (int i = 0; i < 8; i++) { const s16 op1 = vte.element[i]; @@ -1014,11 +1014,11 @@ void RSP::vmulu(const u32 instr) { } } -void RSP::vmudl(const u32 instr) { - const u8 e = E2(instr); - const VPR &vs = vpr[VS(instr)]; - VPR &vd = vpr[VD(instr)]; - SetVTE(vpr[VT(instr)], e); +void RSP::vmudl(const Instruction instr) { + const u8 e = instr.e2(); + const VPR &vs = vpr[instr.vs()]; + VPR &vd = vpr[instr.vd()]; + SetVTE(vpr[instr.vt()], e); for (int i = 0; i < 8; i++) { const u64 op1 = vte.element[i]; const u64 op2 = vs.element[i]; @@ -1040,11 +1040,11 @@ void RSP::vmudl(const u32 instr) { } } -void RSP::vmudh(const u32 instr) { - const int e = E2(instr); - const VPR &vs = vpr[VS(instr)]; - VPR &vd = vpr[VD(instr)]; - SetVTE(vpr[VT(instr)], e); +void RSP::vmudh(const Instruction instr) { + const int e = instr.e2(); + const VPR &vs = vpr[instr.vs()]; + VPR &vd = vpr[instr.vd()]; + SetVTE(vpr[instr.vt()], e); for (int i = 0; i < 8; i++) { const s32 prod = vs.selement[i] * vte.selement[i]; const s16 result = signedClamp(prod); @@ -1055,11 +1055,11 @@ void RSP::vmudh(const u32 instr) { } } -void RSP::vmudm(const u32 instr) { - const int e = E2(instr); - const VPR &vs = vpr[VS(instr)]; - VPR &vd = vpr[VD(instr)]; - SetVTE(vpr[VT(instr)], e); +void RSP::vmudm(const Instruction instr) { + const int e = instr.e2(); + const VPR &vs = vpr[instr.vs()]; + VPR &vd = vpr[instr.vd()]; + SetVTE(vpr[instr.vt()], e); for (int i = 0; i < 8; i++) { const s32 prod = vs.selement[i] * vte.element[i]; const s64 accum = prod; @@ -1070,11 +1070,11 @@ void RSP::vmudm(const u32 instr) { } } -void RSP::vmudn(const u32 instr) { - const int e = E2(instr); - const VPR &vs = vpr[VS(instr)]; - VPR &vd = vpr[VD(instr)]; - SetVTE(vpr[VT(instr)], e); +void RSP::vmudn(const Instruction instr) { + const int e = instr.e2(); + const VPR &vs = vpr[instr.vs()]; + VPR &vd = vpr[instr.vd()]; + SetVTE(vpr[instr.vt()], e); for (int i = 0; i < 8; i++) { const s16 op1 = vte.element[i]; const u16 op2 = vs.element[i]; @@ -1096,11 +1096,11 @@ void RSP::vmudn(const u32 instr) { } #ifdef SIMD_SUPPORT -void RSP::vmadh(const u32 instr) { - const int e = E2(instr); - const VPR &vs = vpr[VS(instr)]; - VPR &vd = vpr[VD(instr)]; - SetVTE(vpr[VT(instr)], e); +void RSP::vmadh(const Instruction instr) { + const int e = instr.e2(); + const VPR &vs = vpr[instr.vs()]; + VPR &vd = vpr[instr.vd()]; + SetVTE(vpr[instr.vt()], e); m128i lo = _mm_mullo_epi16(vs.single, vte.single); m128i hi = _mm_mulhi_epi16(vs.single, vte.single); m128i omask = _mm_adds_epu16(acc.m.single, lo); @@ -1114,11 +1114,11 @@ void RSP::vmadh(const u32 instr) { vd.single = _mm_packs_epi32(lo, hi); } #else -void RSP::vmadh(const u32 instr) { - int e = E2(instr); - VPR &vs = vpr[VS(instr)]; - VPR &vd = vpr[VD(instr)]; - SetVTE(vpr[VT(instr)], e); +void RSP::vmadh(const Instruction instr) { + int e = instr.e2(); + VPR &vs = vpr[instr.vs()]; + VPR &vd = vpr[instr.vd()]; + SetVTE(vpr[instr.vt()], e); for (int i = 0; i < 8; i++) { s16 op1 = vte.element[i]; s16 op2 = vs.element[i]; @@ -1137,11 +1137,11 @@ void RSP::vmadh(const u32 instr) { } #endif -void RSP::vmadl(const u32 instr) { - const int e = E2(instr); - const VPR &vs = vpr[VS(instr)]; - VPR &vd = vpr[VD(instr)]; - SetVTE(vpr[VT(instr)], e); +void RSP::vmadl(const Instruction instr) { + const int e = instr.e2(); + const VPR &vs = vpr[instr.vs()]; + VPR &vd = vpr[instr.vd()]; + SetVTE(vpr[instr.vt()], e); for (int i = 0; i < 8; i++) { const u64 op1 = vte.element[i]; @@ -1165,10 +1165,10 @@ void RSP::vmadl(const u32 instr) { } } #ifdef SIMD_SUPPORT -void RSP::vmadm(const u32 instr) { - const int e = E2(instr); - const VPR &vs = vpr[VS(instr)]; - SetVTE(vpr[VT(instr)], e); +void RSP::vmadm(const Instruction instr) { + const int e = instr.e2(); + const VPR &vs = vpr[instr.vs()]; + SetVTE(vpr[instr.vt()], e); m128i lo = _mm_mullo_epi16(vs.single, vte.single); m128i hi = _mm_mulhi_epu16(vs.single, vte.single); @@ -1189,14 +1189,14 @@ void RSP::vmadm(const u32 instr) { acc.h.single = _mm_sub_epi16(acc.h.single, omask); lo = _mm_unpacklo_epi16(acc.m.single, acc.h.single); hi = _mm_unpackhi_epi16(acc.m.single, acc.h.single); - VPR &vd = vpr[VD(instr)]; + VPR &vd = vpr[instr.vd()]; vd.single = _mm_packs_epi32(lo, hi); } -void RSP::vmadn(const u32 instr) { - const int e = E2(instr); - const VPR &vs = vpr[VS(instr)]; - SetVTE(vpr[VT(instr)], e); +void RSP::vmadn(const Instruction instr) { + const int e = instr.e2(); + const VPR &vs = vpr[instr.vs()]; + SetVTE(vpr[instr.vt()], e); const m128i lo = _mm_mullo_epi16(vs.single, vte.single); m128i hi = _mm_mulhi_epu16(vs.single, vte.single); @@ -1221,15 +1221,15 @@ void RSP::vmadn(const u32 instr) { const m128i smd = _mm_cmpeq_epi16(nhi, nmd); const m128i cmask = _mm_and_si128(smd, shi); const m128i cval = _mm_cmpeq_epi16(nhi, m128i{}); - VPR &vd = vpr[VD(instr)]; + VPR &vd = vpr[instr.vd()]; vd.single = _mm_blendv_epi8(cval, acc.l.single, cmask); } #else -void RSP::vmadm(const u32 instr) { - int e = E2(instr); - VPR &vs = vpr[VS(instr)]; - VPR &vd = vpr[VD(instr)]; - SetVTE(vpr[VT(instr)], e); +void RSP::vmadm(const Instruction instr) { + int e = instr.e2(); + VPR &vs = vpr[instr.vs()]; + VPR &vd = vpr[instr.vd()]; + SetVTE(vpr[instr.vt()], e); for (int i = 0; i < 8; i++) { s32 prod = vs.selement[i] * vte.element[i]; @@ -1244,11 +1244,11 @@ void RSP::vmadm(const u32 instr) { } } -void RSP::vmadn(const u32 instr) { - int e = E2(instr); - VPR &vs = vpr[VS(instr)]; - VPR &vd = vpr[VD(instr)]; - SetVTE(vpr[VT(instr)], e); +void RSP::vmadn(const Instruction instr) { + int e = instr.e2(); + VPR &vs = vpr[instr.vs()]; + VPR &vd = vpr[instr.vd()]; + SetVTE(vpr[instr.vt()], e); for (int i = 0; i < 8; i++) { s32 prod = vs.element[i] * vte.selement[i]; @@ -1270,10 +1270,10 @@ void RSP::vmadn(const u32 instr) { } #endif -void RSP::vmacf(const u32 instr) { - VPR &vd = vpr[VD(instr)]; - const VPR &vs = vpr[VS(instr)]; - SetVTE(vpr[VT(instr)], E2(instr)); +void RSP::vmacf(const Instruction instr) { + VPR &vd = vpr[instr.vd()]; + const VPR &vs = vpr[instr.vs()]; + SetVTE(vpr[instr.vt()], instr.e2()); for (int i = 0; i < 8; i++) { const s16 op1 = vte.element[i]; @@ -1290,10 +1290,10 @@ void RSP::vmacf(const u32 instr) { } } -void RSP::vmacu(const u32 instr) { - VPR &vd = vpr[VD(instr)]; - const VPR &vs = vpr[VS(instr)]; - SetVTE(vpr[VT(instr)], E2(instr)); +void RSP::vmacu(const Instruction instr) { + VPR &vd = vpr[instr.vd()]; + const VPR &vs = vpr[instr.vs()]; + SetVTE(vpr[instr.vt()], instr.e2()); for (int i = 0; i < 8; i++) { const s16 op1 = vte.element[i]; @@ -1309,8 +1309,8 @@ void RSP::vmacu(const u32 instr) { } } -void RSP::vmacq(const u32 instr) { - VPR &vd = vpr[VD(instr)]; +void RSP::vmacq(const Instruction instr) { + VPR &vd = vpr[instr.vd()]; for (int i = 0; i < 8; i++) { s32 product = acc.h.element[i] << 16 | acc.m.element[i]; @@ -1326,11 +1326,11 @@ void RSP::vmacq(const u32 instr) { } } -void RSP::veq(const u32 instr) { - const int e = E2(instr); - VPR &vd = vpr[VD(instr)]; - const VPR &vs = vpr[VS(instr)]; - SetVTE(vpr[VT(instr)], e); +void RSP::veq(const Instruction instr) { + const int e = instr.e2(); + VPR &vd = vpr[instr.vd()]; + const VPR &vs = vpr[instr.vs()]; + SetVTE(vpr[instr.vt()], e); for (int i = 0; i < 8; i++) { vcc.l.element[i] = vco.h.element[i] == 0 && vs.element[i] == vte.element[i] ? 0xffff : 0; @@ -1340,11 +1340,11 @@ void RSP::veq(const u32 instr) { } } -void RSP::vne(const u32 instr) { - const int e = E2(instr); - VPR &vd = vpr[VD(instr)]; - const VPR &vs = vpr[VS(instr)]; - SetVTE(vpr[VT(instr)], e); +void RSP::vne(const Instruction instr) { + const int e = instr.e2(); + VPR &vd = vpr[instr.vd()]; + const VPR &vs = vpr[instr.vs()]; + SetVTE(vpr[instr.vt()], e); for (int i = 0; i < 8; i++) { vcc.l.element[i] = vco.h.element[i] || vs.element[i] != vte.element[i] ? 0xffff : 0; @@ -1354,11 +1354,11 @@ void RSP::vne(const u32 instr) { } } -void RSP::vge(const u32 instr) { - const int e = E2(instr); - VPR &vd = vpr[VD(instr)]; - const VPR &vs = vpr[VS(instr)]; - SetVTE(vpr[VT(instr)], e); +void RSP::vge(const Instruction instr) { + const int e = instr.e2(); + VPR &vd = vpr[instr.vd()]; + const VPR &vs = vpr[instr.vs()]; + SetVTE(vpr[instr.vt()], e); for (int i = 0; i < 8; i++) { const bool eql = vs.selement[i] == vte.selement[i]; @@ -1370,11 +1370,11 @@ void RSP::vge(const u32 instr) { } } -void RSP::vlt(const u32 instr) { - const int e = E2(instr); - VPR &vd = vpr[VD(instr)]; - const VPR &vs = vpr[VS(instr)]; - SetVTE(vpr[VT(instr)], e); +void RSP::vlt(const Instruction instr) { + const int e = instr.e2(); + VPR &vd = vpr[instr.vd()]; + const VPR &vs = vpr[instr.vs()]; + SetVTE(vpr[instr.vt()], e); for (int i = 0; i < 8; i++) { const bool eql = vs.element[i] == vte.element[i]; @@ -1436,11 +1436,11 @@ FORCE_INLINE u32 rsq(u32 input) { return result ^ mask; } -void RSP::vrcpl(const u32 instr) { - VPR &vd = vpr[VD(instr)]; - const VPR &vt = vpr[VT(instr)]; - SetVTE(vpr[VT(instr)], E2(instr)); - const int e = E2(instr) & 7; +void RSP::vrcpl(const Instruction instr) { + VPR &vd = vpr[instr.vd()]; + const VPR &vt = vpr[instr.vt()]; + SetVTE(vpr[instr.vt()], instr.e2()); + const int e = instr.e2() & 7; const int de = DE(instr) & 7; s32 input; @@ -1466,11 +1466,11 @@ void RSP::vrcpl(const u32 instr) { vd.element[ELEMENT_INDEX(de)] = result; } -void RSP::vrcp(const u32 instr) { - VPR &vd = vpr[VD(instr)]; - const VPR &vt = vpr[VT(instr)]; - SetVTE(vpr[VT(instr)], E2(instr)); - const int e = E2(instr) & 7; +void RSP::vrcp(const Instruction instr) { + VPR &vd = vpr[instr.vd()]; + const VPR &vt = vpr[instr.vt()]; + SetVTE(vpr[instr.vt()], instr.e2()); + const int e = instr.e2() & 7; const int de = DE(instr) & 7; const s32 input = vt.selement[ELEMENT_INDEX(e)]; const s32 result = rcp(input); @@ -1487,12 +1487,12 @@ void RSP::vrcp(const u32 instr) { #endif } -void RSP::vrsq(const u32 instr) { - VPR &vd = vpr[VD(instr)]; - const VPR &vt = vpr[VT(instr)]; - SetVTE(vpr[VT(instr)], E2(instr)); - const int e = E2(instr) & 7; - const int de = VS(instr) & 7; +void RSP::vrsq(const Instruction instr) { + VPR &vd = vpr[instr.vd()]; + const VPR &vt = vpr[instr.vt()]; + SetVTE(vpr[instr.vt()], instr.e2()); + const int e = instr.e2() & 7; + const int de = instr.vs() & 7; const s32 input = vt.selement[ELEMENT_INDEX(e)]; const u32 result = rsq(input); vd.element[ELEMENT_INDEX(de)] = result & 0xFFFF; @@ -1515,14 +1515,14 @@ static FORCE_INLINE s64 sclip(const s64 x, const u32 bits) { return ((x & m) ^ b) - b; } -void RSP::vrndn(const u32 instr) { - VPR &vd = vpr[VD(instr)]; - SetVTE(vpr[VT(instr)], E2(instr)); +void RSP::vrndn(const Instruction instr) { + VPR &vd = vpr[instr.vd()]; + SetVTE(vpr[instr.vt()], instr.e2()); for (int i = 0; i < 8; i++) { s32 product = vte.selement[i]; - if (VS(instr) & 1) { + if (instr.vs() & 1) { product <<= 16; } @@ -1546,14 +1546,14 @@ void RSP::vrndn(const u32 instr) { } } -void RSP::vrndp(const u32 instr) { - VPR &vd = vpr[VD(instr)]; - SetVTE(vpr[VT(instr)], E2(instr)); +void RSP::vrndp(const Instruction instr) { + VPR &vd = vpr[instr.vd()]; + SetVTE(vpr[instr.vt()], instr.e2()); for (int i = 0; i < 8; i++) { s32 product = vte.selement[i]; - if (VS(instr) & 1) { + if (instr.vs() & 1) { product <<= 16; } @@ -1577,11 +1577,11 @@ void RSP::vrndp(const u32 instr) { } } -void RSP::vrsql(const u32 instr) { - VPR &vd = vpr[VD(instr)]; - const VPR &vt = vpr[VT(instr)]; - SetVTE(vpr[VT(instr)], E2(instr)); - const int e = E2(instr) & 7; +void RSP::vrsql(const Instruction instr) { + VPR &vd = vpr[instr.vd()]; + const VPR &vt = vpr[instr.vt()]; + SetVTE(vpr[instr.vt()], instr.e2()); + const int e = instr.e2() & 7; const int de = DE(instr) & 7; s32 input; @@ -1606,12 +1606,12 @@ void RSP::vrsql(const u32 instr) { vd.element[ELEMENT_INDEX(de)] = result; } -void RSP::vrcph(const u32 instr) { - const int e = E2(instr) & 7; +void RSP::vrcph(const Instruction instr) { + const int e = instr.e2() & 7; const int de = DE(instr) & 7; - VPR &vd = vpr[VD(instr)]; - const VPR &vt = vpr[VT(instr)]; - SetVTE(vpr[VT(instr)], E2(instr)); + VPR &vd = vpr[instr.vd()]; + const VPR &vt = vpr[instr.vt()]; + SetVTE(vpr[instr.vt()], instr.e2()); #ifdef SIMD_SUPPORT acc.l.single = vte.single; @@ -1626,9 +1626,9 @@ void RSP::vrcph(const u32 instr) { divInLoaded = true; } -void RSP::vsar(const u32 instr) { - const u8 e = E2(instr); - VPR &vd = vpr[VD(instr)]; +void RSP::vsar(const Instruction instr) { + const u8 e = instr.e2(); + VPR &vd = vpr[instr.vd()]; switch (e) { case 0x8: #ifdef SIMD_SUPPORT @@ -1669,11 +1669,11 @@ void RSP::vsar(const u32 instr) { } } -void RSP::vsubc(const u32 instr) { - const int e = E2(instr); - const VPR &vs = vpr[VS(instr)]; - VPR &vd = vpr[VD(instr)]; - SetVTE(vpr[VT(instr)], e); +void RSP::vsubc(const Instruction instr) { + const int e = instr.e2(); + const VPR &vs = vpr[instr.vs()]; + VPR &vd = vpr[instr.vd()]; + SetVTE(vpr[instr.vt()], e); for (int i = 0; i < 8; i++) { const u32 result = vs.element[i] - vte.element[i]; @@ -1685,11 +1685,11 @@ void RSP::vsubc(const u32 instr) { } } -void RSP::vsub(const u32 instr) { - const int e = E2(instr); - const VPR &vs = vpr[VS(instr)]; - VPR &vd = vpr[VD(instr)]; - SetVTE(vpr[VT(instr)], e); +void RSP::vsub(const Instruction instr) { + const int e = instr.e2(); + const VPR &vs = vpr[instr.vs()]; + VPR &vd = vpr[instr.vd()]; + SetVTE(vpr[instr.vt()], e); for (int i = 0; i < 8; i++) { const s32 result = vs.selement[i] - vte.selement[i] - (vco.l.element[i] != 0); @@ -1701,11 +1701,11 @@ void RSP::vsub(const u32 instr) { } } -void RSP::vmrg(const u32 instr) { - const int e = E2(instr); - const VPR &vs = vpr[VS(instr)]; - VPR &vd = vpr[VD(instr)]; - SetVTE(vpr[VT(instr)], e); +void RSP::vmrg(const Instruction instr) { + const int e = instr.e2(); + const VPR &vs = vpr[instr.vs()]; + VPR &vd = vpr[instr.vd()]; + SetVTE(vpr[instr.vt()], e); for (int i = 0; i < 8; i++) { acc.l.element[i] = vcc.l.element[i] ? vs.element[i] : vte.element[i]; @@ -1715,11 +1715,11 @@ void RSP::vmrg(const u32 instr) { } } -void RSP::vxor(const u32 instr) { - const int e = E2(instr); - const VPR &vs = vpr[VS(instr)]; - VPR &vd = vpr[VD(instr)]; - SetVTE(vpr[VT(instr)], e); +void RSP::vxor(const Instruction instr) { + const int e = instr.e2(); + const VPR &vs = vpr[instr.vs()]; + VPR &vd = vpr[instr.vd()]; + SetVTE(vpr[instr.vt()], e); for (int i = 0; i < 8; i++) { acc.l.element[i] = vte.element[i] ^ vs.element[i]; @@ -1727,11 +1727,11 @@ void RSP::vxor(const u32 instr) { } } -void RSP::vnxor(const u32 instr) { - const int e = E2(instr); - const VPR &vs = vpr[VS(instr)]; - VPR &vd = vpr[VD(instr)]; - SetVTE(vpr[VT(instr)], e); +void RSP::vnxor(const Instruction instr) { + const int e = instr.e2(); + const VPR &vs = vpr[instr.vs()]; + VPR &vd = vpr[instr.vd()]; + SetVTE(vpr[instr.vt()], e); for (int i = 0; i < 8; i++) { acc.l.element[i] = ~(vte.element[i] ^ vs.element[i]); @@ -1739,11 +1739,11 @@ void RSP::vnxor(const u32 instr) { } } -void RSP::vand(const u32 instr) { - const int e = E2(instr); - const VPR &vs = vpr[VS(instr)]; - VPR &vd = vpr[VD(instr)]; - SetVTE(vpr[VT(instr)], e); +void RSP::vand(const Instruction instr) { + const int e = instr.e2(); + const VPR &vs = vpr[instr.vs()]; + VPR &vd = vpr[instr.vd()]; + SetVTE(vpr[instr.vt()], e); for (int i = 0; i < 8; i++) { acc.l.element[i] = vte.element[i] & vs.element[i]; @@ -1751,11 +1751,11 @@ void RSP::vand(const u32 instr) { } } -void RSP::vnand(const u32 instr) { - const int e = E2(instr); - const VPR &vs = vpr[VS(instr)]; - VPR &vd = vpr[VD(instr)]; - SetVTE(vpr[VT(instr)], e); +void RSP::vnand(const Instruction instr) { + const int e = instr.e2(); + const VPR &vs = vpr[instr.vs()]; + VPR &vd = vpr[instr.vd()]; + SetVTE(vpr[instr.vt()], e); for (int i = 0; i < 8; i++) { acc.l.element[i] = ~(vte.element[i] & vs.element[i]); @@ -1763,11 +1763,11 @@ void RSP::vnand(const u32 instr) { } } -void RSP::vnor(const u32 instr) { - const int e = E2(instr); - const VPR &vs = vpr[VS(instr)]; - VPR &vd = vpr[VD(instr)]; - SetVTE(vpr[VT(instr)], e); +void RSP::vnor(const Instruction instr) { + const int e = instr.e2(); + const VPR &vs = vpr[instr.vs()]; + VPR &vd = vpr[instr.vd()]; + SetVTE(vpr[instr.vt()], e); for (int i = 0; i < 8; i++) { acc.l.element[i] = ~(vte.element[i] | vs.element[i]); @@ -1775,11 +1775,11 @@ void RSP::vnor(const u32 instr) { } } -void RSP::vor(const u32 instr) { - const int e = E2(instr); - const VPR &vs = vpr[VS(instr)]; - VPR &vd = vpr[VD(instr)]; - SetVTE(vpr[VT(instr)], e); +void RSP::vor(const Instruction instr) { + const int e = instr.e2(); + const VPR &vs = vpr[instr.vs()]; + VPR &vd = vpr[instr.vd()]; + SetVTE(vpr[instr.vt()], e); for (int i = 0; i < 8; i++) { acc.l.element[i] = vte.element[i] | vs.element[i]; @@ -1787,10 +1787,10 @@ void RSP::vor(const u32 instr) { } } -void RSP::vzero(const u32 instr) { - const VPR &vs = vpr[VS(instr)]; - SetVTE(vpr[VT(instr)], E2(instr)); - VPR &vd = vpr[VD(instr)]; +void RSP::vzero(const Instruction instr) { + const VPR &vs = vpr[instr.vs()]; + SetVTE(vpr[instr.vt()], instr.e2()); + VPR &vd = vpr[instr.vd()]; for (int i = 0; i < 8; i++) { acc.l.element[i] = vte.element[i] + vs.element[i]; @@ -1799,27 +1799,27 @@ void RSP::vzero(const u32 instr) { memset(&vd, 0, sizeof(VPR)); } -void RSP::mfc0(const RDP &rdp, const u32 instr) { gpr[RT(instr)] = GetCop0Reg(*this, rdp, RD(instr)); } +void RSP::mfc0(const RDP &rdp, const Instruction instr) { gpr[instr.rt()] = GetCop0Reg(*this, rdp, instr.rd()); } -void RSP::mtc0(const u32 instr) const { +void RSP::mtc0(const Instruction instr) const { Mem& mem = Core::GetMem(); - SetCop0Reg(mem, RD(instr), gpr[RT(instr)]); + SetCop0Reg(mem, instr.rd(), gpr[instr.rt()]); } -void RSP::mfc2(const u32 instr) { - const u8 hi = vpr[RD(instr)].byte[BYTE_INDEX(E1(instr))]; - const u8 lo = vpr[RD(instr)].byte[BYTE_INDEX((E1(instr) + 1) & 0xF)]; +void RSP::mfc2(const Instruction instr) { + const u8 hi = vpr[instr.rd()].byte[BYTE_INDEX(instr.e1())]; + const u8 lo = vpr[instr.rd()].byte[BYTE_INDEX((instr.e1() + 1) & 0xF)]; const s16 elem = hi << 8 | lo; - gpr[RT(instr)] = elem; + gpr[instr.rt()] = elem; } -void RSP::mtc2(const u32 instr) { - const u16 element = gpr[RT(instr)]; +void RSP::mtc2(const Instruction instr) { + const u16 element = gpr[instr.rt()]; const u8 lo = element; const u8 hi = element >> 8; - vpr[RD(instr)].byte[BYTE_INDEX(E1(instr))] = hi; - if (E1(instr) < 15) { - vpr[RD(instr)].byte[BYTE_INDEX(E1(instr) + 1)] = lo; + vpr[instr.rd()].byte[BYTE_INDEX(instr.e1())] = hi; + if (instr.e1() < 15) { + vpr[instr.rd()].byte[BYTE_INDEX(instr.e1() + 1)] = lo; } } } // namespace n64 diff --git a/src/common.hpp b/src/common.hpp index 1420bc90..81a849c2 100644 --- a/src/common.hpp +++ b/src/common.hpp @@ -27,18 +27,6 @@ static FORCE_INLINE constexpr u32 GetVideoFrequency(bool pal) { #define HALF_ADDRESS(addr) ((addr) ^ 2) #define BYTE_ADDRESS(addr) ((addr) ^ 3) -#define RD(x) (((x) >> 11) & 0x1F) -#define RT(x) (((x) >> 16) & 0x1F) -#define RS(x) (((x) >> 21) & 0x1F) -#define FD(x) (((x) >> 6) & 0x1F) -#define FT(x) RT(x) -#define FS(x) RD(x) -#define BASE(x) RS(x) -#define VT(x) (((x) >> 16) & 0x1F) -#define VS(x) (((x) >> 11) & 0x1F) -#define VD(x) (((x) >> 6) & 0x1F) -#define E1(x) (((x) >> 7) & 0x0F) -#define E2(x) (((x) >> 21) & 0x0F) #define ELEMENT_INDEX(i) (7 - (i)) #define BYTE_INDEX(i) (15 - (i)) diff --git a/src/utils/Instruction.hpp b/src/utils/Instruction.hpp index ba3fb380..acc53f6b 100644 --- a/src/utils/Instruction.hpp +++ b/src/utils/Instruction.hpp @@ -16,6 +16,11 @@ struct Instruction { inline u8 ft() const { return rt(); } inline u8 fd() const { return sa(); } inline u8 base() const { return rs(); } + inline u8 vt() const { return rt(); } + inline u8 vs() const { return rd(); } + inline u8 vd() const { return fd(); } + inline u8 e1() const { return (instr.raw >> 7) & 0x0f; } + inline u8 e2() const { return rs() & 0x0f; } inline u16 imm() const { return instr.itype.imm; } inline u32 target() const { return instr.jtype.target; } inline u8 opcode() const { return instr.opcode.op; }