Instruction struct rewrite in RSP too now
This commit is contained in:
@@ -25,7 +25,7 @@ private:
|
|||||||
bool ShouldServiceInterrupt() const;
|
bool ShouldServiceInterrupt() const;
|
||||||
void CheckCompareInterrupt();
|
void CheckCompareInterrupt();
|
||||||
|
|
||||||
void cop2Decode(u32);
|
void cop2Decode(Instruction);
|
||||||
void special(Instruction);
|
void special(Instruction);
|
||||||
void regimm(Instruction);
|
void regimm(Instruction);
|
||||||
void Exec(Instruction);
|
void Exec(Instruction);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <array>
|
#include <array>
|
||||||
#include <core/RDP.hpp>
|
#include <core/RDP.hpp>
|
||||||
#include <core/mmio/MI.hpp>
|
#include <core/mmio/MI.hpp>
|
||||||
|
#include <Instruction.hpp>
|
||||||
|
|
||||||
#define RSP_BYTE(addr) (dmem[BYTE_ADDRESS(addr) & 0xFFF])
|
#define RSP_BYTE(addr) (dmem[BYTE_ADDRESS(addr) & 0xFFF])
|
||||||
#define GET_RSP_HALF(addr) ((RSP_BYTE(addr) << 8) | RSP_BYTE((addr) + 1))
|
#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);
|
void SetVTE(const VPR &vt, u8 e);
|
||||||
auto Read(u32 addr) -> u32;
|
auto Read(u32 addr) -> u32;
|
||||||
void Write(u32 addr, u32 val);
|
void Write(u32 addr, u32 val);
|
||||||
void Exec(u32 instr);
|
void Exec(const Instruction instr);
|
||||||
SPStatus spStatus{};
|
SPStatus spStatus{};
|
||||||
u16 oldPC{}, pc{}, nextPC{};
|
u16 oldPC{}, pc{}, nextPC{};
|
||||||
SPDMASPAddr spDMASPAddr{};
|
SPDMASPAddr spDMASPAddr{};
|
||||||
@@ -256,120 +257,120 @@ struct RSP {
|
|||||||
|
|
||||||
FORCE_INLINE void ReleaseSemaphore() { semaphore = false; }
|
FORCE_INLINE void ReleaseSemaphore() { semaphore = false; }
|
||||||
|
|
||||||
void special(const u32 instr);
|
void special(const Instruction instr);
|
||||||
void regimm(const u32 instr);
|
void regimm(const Instruction instr);
|
||||||
void lwc2(const u32 instr);
|
void lwc2(const Instruction instr);
|
||||||
void swc2(const u32 instr);
|
void swc2(const Instruction instr);
|
||||||
void cop2(const u32 instr);
|
void cop2(const Instruction instr);
|
||||||
void cop0(const u32 instr);
|
void cop0(const Instruction instr);
|
||||||
|
|
||||||
void add(u32 instr);
|
void add(Instruction instr);
|
||||||
void addi(u32 instr);
|
void addi(Instruction instr);
|
||||||
void and_(u32 instr);
|
void and_(Instruction instr);
|
||||||
void andi(u32 instr);
|
void andi(Instruction instr);
|
||||||
void b(u32 instr, bool cond);
|
void b(Instruction instr, bool cond);
|
||||||
void blink(u32 instr, bool cond);
|
void blink(Instruction instr, bool cond);
|
||||||
void cfc2(u32 instr);
|
void cfc2(Instruction instr);
|
||||||
void ctc2(u32 instr);
|
void ctc2(Instruction instr);
|
||||||
void lb(u32 instr);
|
void lb(Instruction instr);
|
||||||
void lh(u32 instr);
|
void lh(Instruction instr);
|
||||||
void lw(u32 instr);
|
void lw(Instruction instr);
|
||||||
void lbu(u32 instr);
|
void lbu(Instruction instr);
|
||||||
void lhu(u32 instr);
|
void lhu(Instruction instr);
|
||||||
void lui(u32 instr);
|
void lui(Instruction instr);
|
||||||
void luv(u32 instr);
|
void luv(Instruction instr);
|
||||||
void lbv(u32 instr);
|
void lbv(Instruction instr);
|
||||||
void ldv(u32 instr);
|
void ldv(Instruction instr);
|
||||||
void lsv(u32 instr);
|
void lsv(Instruction instr);
|
||||||
void llv(u32 instr);
|
void llv(Instruction instr);
|
||||||
void lrv(u32 instr);
|
void lrv(Instruction instr);
|
||||||
void lqv(u32 instr);
|
void lqv(Instruction instr);
|
||||||
void lfv(u32 instr);
|
void lfv(Instruction instr);
|
||||||
void lhv(u32 instr);
|
void lhv(Instruction instr);
|
||||||
void ltv(u32 instr);
|
void ltv(Instruction instr);
|
||||||
void lpv(u32 instr);
|
void lpv(Instruction instr);
|
||||||
void j(u32 instr);
|
void j(Instruction instr);
|
||||||
void jal(u32 instr);
|
void jal(Instruction instr);
|
||||||
void jr(u32 instr);
|
void jr(Instruction instr);
|
||||||
void jalr(u32 instr);
|
void jalr(Instruction instr);
|
||||||
void nor(u32 instr);
|
void nor(Instruction instr);
|
||||||
void or_(u32 instr);
|
void or_(Instruction instr);
|
||||||
void ori(u32 instr);
|
void ori(Instruction instr);
|
||||||
void xor_(u32 instr);
|
void xor_(Instruction instr);
|
||||||
void xori(u32 instr);
|
void xori(Instruction instr);
|
||||||
void sb(u32 instr);
|
void sb(Instruction instr);
|
||||||
void sh(u32 instr);
|
void sh(Instruction instr);
|
||||||
void sw(u32 instr);
|
void sw(Instruction instr);
|
||||||
void swv(u32 instr);
|
void swv(Instruction instr);
|
||||||
void sub(u32 instr);
|
void sub(Instruction instr);
|
||||||
void sbv(u32 instr);
|
void sbv(Instruction instr);
|
||||||
void sdv(u32 instr);
|
void sdv(Instruction instr);
|
||||||
void stv(u32 instr);
|
void stv(Instruction instr);
|
||||||
void sqv(u32 instr);
|
void sqv(Instruction instr);
|
||||||
void ssv(u32 instr);
|
void ssv(Instruction instr);
|
||||||
void suv(u32 instr);
|
void suv(Instruction instr);
|
||||||
void slv(u32 instr);
|
void slv(Instruction instr);
|
||||||
void shv(u32 instr);
|
void shv(Instruction instr);
|
||||||
void sfv(u32 instr);
|
void sfv(Instruction instr);
|
||||||
void srv(u32 instr);
|
void srv(Instruction instr);
|
||||||
void spv(u32 instr);
|
void spv(Instruction instr);
|
||||||
void sllv(u32 instr);
|
void sllv(Instruction instr);
|
||||||
void srlv(u32 instr);
|
void srlv(Instruction instr);
|
||||||
void srav(u32 instr);
|
void srav(Instruction instr);
|
||||||
void sll(u32 instr);
|
void sll(Instruction instr);
|
||||||
void srl(u32 instr);
|
void srl(Instruction instr);
|
||||||
void sra(u32 instr);
|
void sra(Instruction instr);
|
||||||
void slt(u32 instr);
|
void slt(Instruction instr);
|
||||||
void sltu(u32 instr);
|
void sltu(Instruction instr);
|
||||||
void slti(u32 instr);
|
void slti(Instruction instr);
|
||||||
void sltiu(u32 instr);
|
void sltiu(Instruction instr);
|
||||||
void vabs(u32 instr);
|
void vabs(Instruction instr);
|
||||||
void vadd(u32 instr);
|
void vadd(Instruction instr);
|
||||||
void vaddc(u32 instr);
|
void vaddc(Instruction instr);
|
||||||
void vand(u32 instr);
|
void vand(Instruction instr);
|
||||||
void vnand(u32 instr);
|
void vnand(Instruction instr);
|
||||||
void vch(u32 instr);
|
void vch(Instruction instr);
|
||||||
void vcr(u32 instr);
|
void vcr(Instruction instr);
|
||||||
void vcl(u32 instr);
|
void vcl(Instruction instr);
|
||||||
void vmacf(u32 instr);
|
void vmacf(Instruction instr);
|
||||||
void vmacu(u32 instr);
|
void vmacu(Instruction instr);
|
||||||
void vmacq(u32 instr);
|
void vmacq(Instruction instr);
|
||||||
void vmadh(u32 instr);
|
void vmadh(Instruction instr);
|
||||||
void vmadl(u32 instr);
|
void vmadl(Instruction instr);
|
||||||
void vmadm(u32 instr);
|
void vmadm(Instruction instr);
|
||||||
void vmadn(u32 instr);
|
void vmadn(Instruction instr);
|
||||||
void vmov(u32 instr);
|
void vmov(Instruction instr);
|
||||||
void vmulf(u32 instr);
|
void vmulf(Instruction instr);
|
||||||
void vmulu(u32 instr);
|
void vmulu(Instruction instr);
|
||||||
void vmulq(u32 instr);
|
void vmulq(Instruction instr);
|
||||||
void vmudl(u32 instr);
|
void vmudl(Instruction instr);
|
||||||
void vmudh(u32 instr);
|
void vmudh(Instruction instr);
|
||||||
void vmudm(u32 instr);
|
void vmudm(Instruction instr);
|
||||||
void vmudn(u32 instr);
|
void vmudn(Instruction instr);
|
||||||
void vmrg(u32 instr);
|
void vmrg(Instruction instr);
|
||||||
void vlt(u32 instr);
|
void vlt(Instruction instr);
|
||||||
void veq(u32 instr);
|
void veq(Instruction instr);
|
||||||
void vne(u32 instr);
|
void vne(Instruction instr);
|
||||||
void vge(u32 instr);
|
void vge(Instruction instr);
|
||||||
void vrcp(u32 instr);
|
void vrcp(Instruction instr);
|
||||||
void vrsq(u32 instr);
|
void vrsq(Instruction instr);
|
||||||
void vrcpl(u32 instr);
|
void vrcpl(Instruction instr);
|
||||||
void vrsql(u32 instr);
|
void vrsql(Instruction instr);
|
||||||
void vrndp(u32 instr);
|
void vrndp(Instruction instr);
|
||||||
void vrndn(u32 instr);
|
void vrndn(Instruction instr);
|
||||||
void vrcph(u32 instr);
|
void vrcph(Instruction instr);
|
||||||
void vsar(u32 instr);
|
void vsar(Instruction instr);
|
||||||
void vsub(u32 instr);
|
void vsub(Instruction instr);
|
||||||
void vsubc(u32 instr);
|
void vsubc(Instruction instr);
|
||||||
void vxor(u32 instr);
|
void vxor(Instruction instr);
|
||||||
void vnxor(u32 instr);
|
void vnxor(Instruction instr);
|
||||||
void vor(u32 instr);
|
void vor(Instruction instr);
|
||||||
void vnor(u32 instr);
|
void vnor(Instruction instr);
|
||||||
void vzero(u32 instr);
|
void vzero(Instruction instr);
|
||||||
void mfc0(const RDP &rdp, u32 instr);
|
void mfc0(const RDP &rdp, Instruction instr);
|
||||||
void mtc0(u32 instr) const;
|
void mtc0(Instruction instr) const;
|
||||||
void mfc2(u32 instr);
|
void mfc2(Instruction instr);
|
||||||
void mtc2(u32 instr);
|
void mtc2(Instruction instr);
|
||||||
|
|
||||||
template <bool toRdram>
|
template <bool toRdram>
|
||||||
void DMA();
|
void DMA();
|
||||||
|
|||||||
@@ -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) {
|
if (!regs.cop0.status.cu2) {
|
||||||
regs.cop0.FireException(ExceptionCode::CoprocessorUnusable, 2, regs.oldPC);
|
regs.cop0.FireException(ExceptionCode::CoprocessorUnusable, 2, regs.oldPC);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switch (RS(instr)) {
|
switch (instr.rs()) {
|
||||||
case 0x00:
|
case 0x00:
|
||||||
mfc2(instr);
|
mfc2(instr);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -127,22 +127,22 @@ void JIT::special(const Instruction instr) {
|
|||||||
dsubu(instr);
|
dsubu(instr);
|
||||||
break;
|
break;
|
||||||
case Instruction::TGE:
|
case Instruction::TGE:
|
||||||
trap(regs.Read<s64>(RS(instr)) >= regs.Read<s64>(RT(instr)));
|
trap(regs.Read<s64>(instr.rs()) >= regs.Read<s64>(instr.rt()));
|
||||||
break;
|
break;
|
||||||
case Instruction::TGEU:
|
case Instruction::TGEU:
|
||||||
trap(regs.Read<u64>(RS(instr)) >= regs.Read<u64>(RT(instr)));
|
trap(regs.Read<u64>(instr.rs()) >= regs.Read<u64>(instr.rt()));
|
||||||
break;
|
break;
|
||||||
case Instruction::TLT:
|
case Instruction::TLT:
|
||||||
trap(regs.Read<s64>(RS(instr)) < regs.Read<s64>(RT(instr)));
|
trap(regs.Read<s64>(instr.rs()) < regs.Read<s64>(instr.rt()));
|
||||||
break;
|
break;
|
||||||
case Instruction::TLTU:
|
case Instruction::TLTU:
|
||||||
trap(regs.Read<u64>(RS(instr)) < regs.Read<u64>(RT(instr)));
|
trap(regs.Read<u64>(instr.rs()) < regs.Read<u64>(instr.rt()));
|
||||||
break;
|
break;
|
||||||
case Instruction::TEQ:
|
case Instruction::TEQ:
|
||||||
trap(regs.Read<s64>(RS(instr)) == regs.Read<s64>(RT(instr)));
|
trap(regs.Read<s64>(instr.rs()) == regs.Read<s64>(instr.rt()));
|
||||||
break;
|
break;
|
||||||
case Instruction::TNE:
|
case Instruction::TNE:
|
||||||
trap(regs.Read<s64>(RS(instr)) != regs.Read<s64>(RT(instr)));
|
trap(regs.Read<s64>(instr.rs()) != regs.Read<s64>(instr.rt()));
|
||||||
break;
|
break;
|
||||||
case Instruction::DSLL:
|
case Instruction::DSLL:
|
||||||
dsll(instr);
|
dsll(instr);
|
||||||
@@ -184,22 +184,22 @@ void JIT::regimm(const Instruction instr) {
|
|||||||
bgezl(instr);
|
bgezl(instr);
|
||||||
break;
|
break;
|
||||||
case Instruction::TGEI:
|
case Instruction::TGEI:
|
||||||
trap(regs.Read<s64>(RS(instr)) >= static_cast<s64>(static_cast<s16>(instr)));
|
trap(regs.Read<s64>(instr.rs()) >= static_cast<s64>(static_cast<s16>(instr)));
|
||||||
break;
|
break;
|
||||||
case Instruction::TGEIU:
|
case Instruction::TGEIU:
|
||||||
trap(regs.Read<u64>(RS(instr)) >= static_cast<u64>(static_cast<s64>(static_cast<s16>(instr))));
|
trap(regs.Read<u64>(instr.rs()) >= static_cast<u64>(static_cast<s64>(static_cast<s16>(instr))));
|
||||||
break;
|
break;
|
||||||
case Instruction::TLTI:
|
case Instruction::TLTI:
|
||||||
trap(regs.Read<s64>(RS(instr)) < static_cast<s64>(static_cast<s16>(instr)));
|
trap(regs.Read<s64>(instr.rs()) < static_cast<s64>(static_cast<s16>(instr)));
|
||||||
break;
|
break;
|
||||||
case Instruction::TLTIU:
|
case Instruction::TLTIU:
|
||||||
trap(regs.Read<u64>(RS(instr)) < static_cast<u64>(static_cast<s64>(static_cast<s16>(instr))));
|
trap(regs.Read<u64>(instr.rs()) < static_cast<u64>(static_cast<s64>(static_cast<s16>(instr))));
|
||||||
break;
|
break;
|
||||||
case Instruction::TEQI:
|
case Instruction::TEQI:
|
||||||
trap(regs.Read<s64>(RS(instr)) == static_cast<s64>(static_cast<s16>(instr)));
|
trap(regs.Read<s64>(instr.rs()) == static_cast<s64>(static_cast<s16>(instr)));
|
||||||
break;
|
break;
|
||||||
case Instruction::TNEI:
|
case Instruction::TNEI:
|
||||||
trap(regs.Read<s64>(RS(instr)) != static_cast<s64>(static_cast<s16>(instr)));
|
trap(regs.Read<s64>(instr.rs()) != static_cast<s64>(static_cast<s16>(instr)));
|
||||||
break;
|
break;
|
||||||
case Instruction::BLTZAL:
|
case Instruction::BLTZAL:
|
||||||
bltzal(instr);
|
bltzal(instr);
|
||||||
|
|||||||
@@ -949,8 +949,8 @@ void JIT::ld(const Instruction instr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void JIT::ldc1(const Instruction instr) {
|
void JIT::ldc1(const Instruction instr) {
|
||||||
if (regs.IsRegConstant(BASE(instr))) {
|
if (regs.IsRegConstant(instr.base())) {
|
||||||
const u64 addr = static_cast<s64>(static_cast<s16>(instr)) + regs.Read<s64>(BASE(instr));
|
const u64 addr = static_cast<s64>(static_cast<s16>(instr)) + regs.Read<s64>(instr.base());
|
||||||
|
|
||||||
if (u32 physical; !regs.cop0.MapVAddr(Cop0::LOAD, addr, physical)) {
|
if (u32 physical; !regs.cop0.MapVAddr(Cop0::LOAD, addr, physical)) {
|
||||||
// regs.cop0.HandleTLBException(addr);
|
// regs.cop0.HandleTLBException(addr);
|
||||||
@@ -958,8 +958,8 @@ void JIT::ldc1(const Instruction instr) {
|
|||||||
panic("[JIT]: Unhandled TLBL exception in LD1!");
|
panic("[JIT]: Unhandled TLBL exception in LD1!");
|
||||||
} else {
|
} else {
|
||||||
const u64 data = mem.Read<u64>(physical);
|
const u64 data = mem.Read<u64>(physical);
|
||||||
regs.cop1.FGR_T<u64>(regs.cop0.status, FT(instr)) = data;
|
regs.cop1.FGR_T<u64>(regs.cop0.status, instr.ft()) = data;
|
||||||
regs.cop1.fgrIsConstant[FT(instr)] = true;
|
regs.cop1.fgrIsConstant[instr.ft()] = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
panic("[JIT]: Implement non constant LD1!");
|
panic("[JIT]: Implement non constant LD1!");
|
||||||
|
|||||||
@@ -2,9 +2,9 @@
|
|||||||
#include <log.hpp>
|
#include <log.hpp>
|
||||||
|
|
||||||
namespace n64 {
|
namespace n64 {
|
||||||
void RSP::special(const u32 instr) {
|
void RSP::special(const Instruction instr) {
|
||||||
MI& mi = Core::GetMem().mmio.mi;
|
MI& mi = Core::GetMem().mmio.mi;
|
||||||
switch (const u8 mask = instr & 0x3f) {
|
switch (instr.cop_funct()) {
|
||||||
case 0x00:
|
case 0x00:
|
||||||
if (instr != 0) {
|
if (instr != 0) {
|
||||||
sll(instr);
|
sll(instr);
|
||||||
@@ -66,31 +66,31 @@ void RSP::special(const u32 instr) {
|
|||||||
sltu(instr);
|
sltu(instr);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
panic("Unhandled RSP special instruction ({:06b})", mask);
|
panic("Unhandled RSP special instruction ({:06b})", instr.cop_funct());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RSP::regimm(const u32 instr) {
|
void RSP::regimm(const Instruction instr) {
|
||||||
switch (const u8 mask = instr >> 16 & 0x1F) {
|
switch (instr.cop_rt()) {
|
||||||
case 0x00:
|
case 0x00:
|
||||||
b(instr, gpr[RS(instr)] < 0);
|
b(instr, gpr[instr.rs()] < 0);
|
||||||
break;
|
break;
|
||||||
case 0x01:
|
case 0x01:
|
||||||
b(instr, gpr[RS(instr)] >= 0);
|
b(instr, gpr[instr.rs()] >= 0);
|
||||||
break;
|
break;
|
||||||
case 0x10:
|
case 0x10:
|
||||||
blink(instr, gpr[RS(instr)] < 0);
|
blink(instr, gpr[instr.rs()] < 0);
|
||||||
break;
|
break;
|
||||||
case 0x11:
|
case 0x11:
|
||||||
blink(instr, gpr[RS(instr)] >= 0);
|
blink(instr, gpr[instr.rs()] >= 0);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
panic("Unhandled RSP regimm instruction ({:05b})", mask);
|
panic("Unhandled RSP regimm instruction ({:05b})", instr.cop_rt());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RSP::lwc2(const u32 instr) {
|
void RSP::lwc2(const Instruction instr) {
|
||||||
switch (const u8 mask = instr >> 11 & 0x1F) {
|
switch (instr.rd()) {
|
||||||
case 0x00:
|
case 0x00:
|
||||||
lbv(instr);
|
lbv(instr);
|
||||||
break;
|
break;
|
||||||
@@ -127,12 +127,12 @@ void RSP::lwc2(const u32 instr) {
|
|||||||
ltv(instr);
|
ltv(instr);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
panic("Unhandled RSP LWC2 {:05b}", mask);
|
panic("Unhandled RSP LWC2 {:05b}", instr.rd());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RSP::swc2(const u32 instr) {
|
void RSP::swc2(const Instruction instr) {
|
||||||
switch (const u8 mask = instr >> 11 & 0x1F) {
|
switch (instr.rd()) {
|
||||||
case 0x00:
|
case 0x00:
|
||||||
sbv(instr);
|
sbv(instr);
|
||||||
break;
|
break;
|
||||||
@@ -170,18 +170,17 @@ void RSP::swc2(const u32 instr) {
|
|||||||
stv(instr);
|
stv(instr);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
panic("Unhandled RSP SWC2 {:05b}", mask);
|
panic("Unhandled RSP SWC2 {:05b}", instr.rd());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RSP::cop2(const u32 instr) {
|
void RSP::cop2(const Instruction instr) {
|
||||||
const u8 mask_sub = instr >> 21 & 0x1F;
|
switch (instr.cop_funct()) {
|
||||||
switch (const u8 mask = instr & 0x3F) {
|
|
||||||
case 0x00:
|
case 0x00:
|
||||||
if (instr >> 25 & 1) {
|
if (instr >> 25 & 1) {
|
||||||
vmulf(instr);
|
vmulf(instr);
|
||||||
} else {
|
} else {
|
||||||
switch (mask_sub) {
|
switch (instr.cop_rs()) {
|
||||||
case 0x00:
|
case 0x00:
|
||||||
mfc2(instr);
|
mfc2(instr);
|
||||||
break;
|
break;
|
||||||
@@ -195,7 +194,7 @@ void RSP::cop2(const u32 instr) {
|
|||||||
ctc2(instr);
|
ctc2(instr);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
panic("Unhandled RSP COP2 sub ({:05b})", mask_sub);
|
panic("Unhandled RSP COP2 sub ({:05b})", instr.cop_rs());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -340,13 +339,13 @@ void RSP::cop2(const u32 instr) {
|
|||||||
case 0x3F:
|
case 0x3F:
|
||||||
break;
|
break;
|
||||||
default:
|
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) {
|
if ((instr & 0x7FF) == 0) {
|
||||||
switch (const u8 mask = instr >> 21 & 0x1F) {
|
switch (instr.cop_rs()) {
|
||||||
case 0x00:
|
case 0x00:
|
||||||
mfc0(Core::GetMem().mmio.rdp, instr);
|
mfc0(Core::GetMem().mmio.rdp, instr);
|
||||||
break;
|
break;
|
||||||
@@ -354,18 +353,18 @@ void RSP::cop0(const u32 instr) {
|
|||||||
mtc0(instr);
|
mtc0(instr);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
panic("Unhandled RSP COP0 ({:05b})", mask);
|
panic("Unhandled RSP COP0 ({:05b})", instr.cop_rs());
|
||||||
}
|
}
|
||||||
} else {
|
} 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();
|
Mem& mem = Core::GetMem();
|
||||||
MMIO &mmio = mem.mmio;
|
MMIO &mmio = mem.mmio;
|
||||||
MI &mi = mmio.mi;
|
MI &mi = mmio.mi;
|
||||||
switch (const u8 mask = instr >> 26 & 0x3F) {
|
switch (instr.opcode()) {
|
||||||
case 0x00:
|
case 0x00:
|
||||||
special(instr);
|
special(instr);
|
||||||
break;
|
break;
|
||||||
@@ -379,16 +378,16 @@ void RSP::Exec(const u32 instr) {
|
|||||||
jal(instr);
|
jal(instr);
|
||||||
break;
|
break;
|
||||||
case 0x04:
|
case 0x04:
|
||||||
b(instr, gpr[RT(instr)] == gpr[RS(instr)]);
|
b(instr, gpr[instr.rt()] == gpr[instr.rs()]);
|
||||||
break;
|
break;
|
||||||
case 0x05:
|
case 0x05:
|
||||||
b(instr, gpr[RT(instr)] != gpr[RS(instr)]);
|
b(instr, gpr[instr.rt()] != gpr[instr.rs()]);
|
||||||
break;
|
break;
|
||||||
case 0x06:
|
case 0x06:
|
||||||
b(instr, gpr[RS(instr)] <= 0);
|
b(instr, gpr[instr.rs()] <= 0);
|
||||||
break;
|
break;
|
||||||
case 0x07:
|
case 0x07:
|
||||||
b(instr, gpr[RS(instr)] > 0);
|
b(instr, gpr[instr.rs()] > 0);
|
||||||
break;
|
break;
|
||||||
case 0x08:
|
case 0x08:
|
||||||
case 0x09:
|
case 0x09:
|
||||||
@@ -451,7 +450,7 @@ void RSP::Exec(const u32 instr) {
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
mem.DumpIMEM();
|
mem.DumpIMEM();
|
||||||
panic("Unhandled RSP instruction ({:06b}, {:04X})", mask, oldPC);
|
panic("Unhandled RSP instruction ({:06b}, {:04X})", instr.opcode(), oldPC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // namespace n64
|
} // namespace n64
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -27,18 +27,6 @@ static FORCE_INLINE constexpr u32 GetVideoFrequency(bool pal) {
|
|||||||
#define HALF_ADDRESS(addr) ((addr) ^ 2)
|
#define HALF_ADDRESS(addr) ((addr) ^ 2)
|
||||||
#define BYTE_ADDRESS(addr) ((addr) ^ 3)
|
#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 ELEMENT_INDEX(i) (7 - (i))
|
||||||
#define BYTE_INDEX(i) (15 - (i))
|
#define BYTE_INDEX(i) (15 - (i))
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,11 @@ struct Instruction {
|
|||||||
inline u8 ft() const { return rt(); }
|
inline u8 ft() const { return rt(); }
|
||||||
inline u8 fd() const { return sa(); }
|
inline u8 fd() const { return sa(); }
|
||||||
inline u8 base() const { return rs(); }
|
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 u16 imm() const { return instr.itype.imm; }
|
||||||
inline u32 target() const { return instr.jtype.target; }
|
inline u32 target() const { return instr.jtype.target; }
|
||||||
inline u8 opcode() const { return instr.opcode.op; }
|
inline u8 opcode() const { return instr.opcode.op; }
|
||||||
|
|||||||
Reference in New Issue
Block a user