Jit a little more (vfpu single load/store, transfer instructions)

This commit is contained in:
Henrik Rydgard 2013-02-10 12:14:55 +01:00
parent 87c9aa99c2
commit 78923f5538
14 changed files with 198 additions and 36 deletions

View file

@ -277,6 +277,12 @@ namespace MIPSComp
}
}
void Jit::Comp_Special3(u32 op)
{
// ext, ins
DISABLE;
}
void Jit::Comp_Allegrex(u32 op)
{
DISABLE

View file

@ -28,7 +28,8 @@
#define _POS ((op>>6 ) & 0x1F)
#define _SIZE ((op>>11 ) & 0x1F)
#define OLDD Comp_Generic(op); return;
#define CONDITIONAL_DISABLE ;
#define DISABLE Comp_Generic(op); return;
namespace MIPSComp
{
@ -61,7 +62,7 @@ void Jit::CompFPTriArith(u32 op, void (XEmitter::*arith)(X64Reg reg, OpArg), boo
void Jit::Comp_FPU3op(u32 op)
{
OLDD
DISABLE
switch (op & 0x3f)
{
//case 0: CompFPTriArith(op, &XEmitter::ADDSS, false); break; //F(fd) = F(fs) + F(ft); //add
@ -76,7 +77,7 @@ void Jit::Comp_FPU3op(u32 op)
void Jit::Comp_FPULS(u32 op)
{
OLDD
DISABLE
s32 offset = (s16)(op&0xFFFF);
int ft = ((op>>16)&0x1f);
@ -113,9 +114,13 @@ void Jit::Comp_FPULS(u32 op)
}
}
void Jit::Comp_FPUComp(u32 op) {
DISABLE;
}
void Jit::Comp_FPU2op(u32 op)
{
OLDD
DISABLE
int fs = _FS;
int fd = _FD;
@ -174,7 +179,7 @@ void Jit::Comp_FPU2op(u32 op)
void Jit::Comp_mxc1(u32 op)
{
OLDD
DISABLE
int fs = _FS;
int rt = _RT;

View file

@ -52,7 +52,7 @@
#define _POS ((op>>6 ) & 0x1F)
#define _SIZE ((op>>11 ) & 0x1F)
#define OLDD Comp_Generic(op); return;
#define DISABLE Comp_Generic(op); return;
namespace MIPSComp
{

View file

@ -29,4 +29,14 @@ namespace MIPSComp
{
DISABLE;
}
void Jit::Comp_Mftv(u32 op)
{
DISABLE;
}
void Jit::Comp_SV(u32 op) {
DISABLE;
}
}

View file

@ -290,6 +290,7 @@ void Jit::LogBlockNumber()
INFO_LOG(CPU, "Block number: %i", blocks.GetNumBlocks() - 1);
}
void Jit::Comp_DoNothing(u32 op) { }
#define _RS ((op>>21) & 0x1F)
#define _RT ((op>>16) & 0x1F)

View file

@ -86,6 +86,7 @@ public:
void Comp_RelBranchRI(u32 op);
void Comp_FPUBranch(u32 op);
void Comp_FPULS(u32 op);
void Comp_FPUComp(u32 op);
void Comp_Jump(u32 op);
void Comp_JumpReg(u32 op);
void Comp_Syscall(u32 op);
@ -96,13 +97,18 @@ public:
void Comp_ShiftType(u32 op);
void Comp_Allegrex(u32 op);
void Comp_VBranch(u32 op);
void Comp_VDot(u32 op);
void Comp_MulDivType(u32 op);
void Comp_Special3(u32 op);
void Comp_FPU3op(u32 op);
void Comp_FPU2op(u32 op);
void Comp_mxc1(u32 op);
void Comp_Mftv(u32 op);
void Comp_VDot(u32 op);
void Comp_DoNothing(u32 op);
void Comp_SV(u32 op);
void Comp_SVQ(u32 op);
ArmJitBlockCache *GetBlockCache() { return &blocks; }

View file

@ -147,7 +147,7 @@ const MIPSInstruction tableImmediate[64] = //xxxxxx .....
//48
INSTR("ll", &Jit::Comp_Generic, Dis_Generic, Int_StoreSync, 0),
INSTR("lwc1", &Jit::Comp_FPULS, Dis_FPULS, Int_FPULS, IN_RT|IN_RS_ADDR),
INSTR("lv.s", &Jit::Comp_Generic, Dis_SV, Int_SV, IS_VFPU),
INSTR("lv.s", &Jit::Comp_SV, Dis_SV, Int_SV, IS_VFPU),
{-2}, // HIT THIS IN WIPEOUT
{VFPU4Jump},
INSTR("lv", &Jit::Comp_SVQ, Dis_SVLRQ, Int_SVQ, IS_VFPU),
@ -156,7 +156,7 @@ const MIPSInstruction tableImmediate[64] = //xxxxxx .....
//56
INSTR("sc", &Jit::Comp_Generic, Dis_Generic, Int_StoreSync, 0),
INSTR("swc1", &Jit::Comp_FPULS, Dis_FPULS, Int_FPULS, 0), //copU
INSTR("sv.s", &Jit::Comp_Generic, Dis_SV, Int_SV,IS_VFPU),
INSTR("sv.s", &Jit::Comp_SV, Dis_SV, Int_SV,IS_VFPU),
{-2},
//60
{VFPU6},
@ -185,7 +185,7 @@ const MIPSInstruction tableSpecial[64] = /// 000000 ...... ...... .......... xxx
INSTR("syscall", &Jit::Comp_Syscall, Dis_Syscall, Int_Syscall,0),
INSTR("break", &Jit::Comp_Break, Dis_Generic, Int_Break, 0),
{-2},
INSTR("sync", &Jit::Comp_Generic, Dis_Generic, Int_Sync, 0),
INSTR("sync", &Jit::Comp_DoNothing, Dis_Generic, Int_Sync, 0),
//16
INSTR("mfhi", &Jit::Comp_MulDivType, Dis_FromHiloTransfer, Int_MulDivType, OUT_RD|IN_OTHER),
@ -224,8 +224,8 @@ const MIPSInstruction tableSpecial[64] = /// 000000 ...... ...... .......... xxx
INSTR("sltu", &Jit::Comp_RType3, Dis_RType3, Int_RType3,IN_RS|IN_RT|OUT_RD),
INSTR("max", &Jit::Comp_RType3, Dis_RType3, Int_RType3,IN_RS|IN_RT|OUT_RD),
INSTR("min", &Jit::Comp_RType3, Dis_RType3, Int_RType3,IN_RS|IN_RT|OUT_RD),
INSTR("msub", &Jit::Comp_Generic, Dis_MulDivType, Int_MulDivType, IN_RS|IN_RT|OUT_OTHER),
INSTR("msubu", &Jit::Comp_Generic, Dis_MulDivType, Int_MulDivType, IN_RS|IN_RT|OUT_OTHER),
INSTR("msub", &Jit::Comp_RType3, Dis_MulDivType, Int_MulDivType, IN_RS|IN_RT|OUT_OTHER),
INSTR("msubu", &Jit::Comp_RType3, Dis_MulDivType, Int_MulDivType, IN_RS|IN_RT|OUT_OTHER),
//48
INSTR("tge", &Jit::Comp_Generic, Dis_RType3, 0, 0),
@ -276,32 +276,32 @@ const MIPSInstruction tableSpecial2[64] =
//40
{-2}, {-2}, {-2}, {-2}, {-2}, {-2}, {-2}, {-2},
//48
INSTR("c.f", &Jit::Comp_Generic, Dis_FPUComp, Int_FPUComp, OUT_FPUFLAG),
INSTR("c.un", &Jit::Comp_Generic, Dis_FPUComp, Int_FPUComp, OUT_FPUFLAG),
INSTR("c.eq", &Jit::Comp_Generic, Dis_FPUComp, Int_FPUComp, OUT_FPUFLAG),
INSTR("c.ueq", &Jit::Comp_Generic, Dis_FPUComp, Int_FPUComp, OUT_FPUFLAG),
INSTR("c.olt", &Jit::Comp_Generic, Dis_FPUComp, Int_FPUComp, OUT_FPUFLAG),
INSTR("c.ult", &Jit::Comp_Generic, Dis_FPUComp, Int_FPUComp, OUT_FPUFLAG),
INSTR("c.ole", &Jit::Comp_Generic, Dis_FPUComp, Int_FPUComp, OUT_FPUFLAG),
INSTR("c.ule", &Jit::Comp_Generic, Dis_FPUComp, Int_FPUComp, OUT_FPUFLAG),
INSTR("c.sf", &Jit::Comp_Generic, Dis_FPUComp, Int_FPUComp, OUT_FPUFLAG),
INSTR("c.ngle",&Jit::Comp_Generic, Dis_FPUComp, Int_FPUComp, OUT_FPUFLAG),
INSTR("c.seq", &Jit::Comp_Generic, Dis_FPUComp, Int_FPUComp, OUT_FPUFLAG),
INSTR("c.ngl", &Jit::Comp_Generic, Dis_FPUComp, Int_FPUComp, OUT_FPUFLAG),
INSTR("c.lt", &Jit::Comp_Generic, Dis_FPUComp, Int_FPUComp, OUT_FPUFLAG),
INSTR("c.nge", &Jit::Comp_Generic, Dis_FPUComp, Int_FPUComp, OUT_FPUFLAG),
INSTR("c.le", &Jit::Comp_Generic, Dis_FPUComp, Int_FPUComp, OUT_FPUFLAG),
INSTR("c.ngt", &Jit::Comp_Generic, Dis_FPUComp, Int_FPUComp, OUT_FPUFLAG),
INSTR("c.f", &Jit::Comp_FPUComp, Dis_FPUComp, Int_FPUComp, OUT_FPUFLAG),
INSTR("c.un", &Jit::Comp_FPUComp, Dis_FPUComp, Int_FPUComp, OUT_FPUFLAG),
INSTR("c.eq", &Jit::Comp_FPUComp, Dis_FPUComp, Int_FPUComp, OUT_FPUFLAG),
INSTR("c.ueq", &Jit::Comp_FPUComp, Dis_FPUComp, Int_FPUComp, OUT_FPUFLAG),
INSTR("c.olt", &Jit::Comp_FPUComp, Dis_FPUComp, Int_FPUComp, OUT_FPUFLAG),
INSTR("c.ult", &Jit::Comp_FPUComp, Dis_FPUComp, Int_FPUComp, OUT_FPUFLAG),
INSTR("c.ole", &Jit::Comp_FPUComp, Dis_FPUComp, Int_FPUComp, OUT_FPUFLAG),
INSTR("c.ule", &Jit::Comp_FPUComp, Dis_FPUComp, Int_FPUComp, OUT_FPUFLAG),
INSTR("c.sf", &Jit::Comp_FPUComp, Dis_FPUComp, Int_FPUComp, OUT_FPUFLAG),
INSTR("c.ngle",&Jit::Comp_FPUComp, Dis_FPUComp, Int_FPUComp, OUT_FPUFLAG),
INSTR("c.seq", &Jit::Comp_FPUComp, Dis_FPUComp, Int_FPUComp, OUT_FPUFLAG),
INSTR("c.ngl", &Jit::Comp_FPUComp, Dis_FPUComp, Int_FPUComp, OUT_FPUFLAG),
INSTR("c.lt", &Jit::Comp_FPUComp, Dis_FPUComp, Int_FPUComp, OUT_FPUFLAG),
INSTR("c.nge", &Jit::Comp_FPUComp, Dis_FPUComp, Int_FPUComp, OUT_FPUFLAG),
INSTR("c.le", &Jit::Comp_FPUComp, Dis_FPUComp, Int_FPUComp, OUT_FPUFLAG),
INSTR("c.ngt", &Jit::Comp_FPUComp, Dis_FPUComp, Int_FPUComp, OUT_FPUFLAG),
};
const MIPSInstruction tableSpecial3[64] =
{
INSTR("ext", &Jit::Comp_Generic, Dis_Special3, Int_Special3, IN_RS|OUT_RT),
INSTR("ext", &Jit::Comp_Special3, Dis_Special3, Int_Special3, IN_RS|OUT_RT),
{-2},
{-2},
{-2},
INSTR("ins", &Jit::Comp_Generic, Dis_Special3, Int_Special3, IN_RS|OUT_RT),
INSTR("ins", &Jit::Comp_Special3, Dis_Special3, Int_Special3, IN_RS|OUT_RT),
{-2},
{-2},
{-2},
@ -363,11 +363,11 @@ const MIPSInstruction tableCop2[32] =
INSTR("mfc2", &Jit::Comp_Generic, Dis_Generic, 0, OUT_RT),
{-2},
INSTR("cfc2", &Jit::Comp_Generic, Dis_Generic, 0, 0),
INSTR("mfv", &Jit::Comp_Generic, Dis_Mftv, Int_Mftv, 0),
INSTR("mfv", &Jit::Comp_Mftv, Dis_Mftv, Int_Mftv, 0),
INSTR("mtc2", &Jit::Comp_Generic, Dis_Generic, 0, IN_RT),
{-2},
INSTR("ctc2", &Jit::Comp_Generic, Dis_Generic, 0, 0),
INSTR("mtv", &Jit::Comp_Generic, Dis_Mftv, Int_Mftv, 0),
INSTR("mtv", &Jit::Comp_Mftv, Dis_Mftv, Int_Mftv, 0),
{Cop2BC2},
INSTR("??", &Jit::Comp_Generic, Dis_Generic, 0, 0),

View file

@ -335,6 +335,13 @@ namespace MIPSComp
}
}
void Jit::Comp_Special3(u32 op)
{
// ext, ins
DISABLE;
}
void Jit::Comp_Allegrex(u32 op)
{
CONDITIONAL_DISABLE

View file

@ -147,8 +147,11 @@ void Jit::Comp_FPULS(u32 op)
static const u64 GC_ALIGNED16(ssSignBits2[2]) = {0x8000000080000000ULL, 0x8000000080000000ULL};
static const u64 GC_ALIGNED16(ssNoSignMask[2]) = {0x7FFFFFFF7FFFFFFFULL, 0x7FFFFFFF7FFFFFFFULL};
void Jit::Comp_FPU2op(u32 op)
{
void Jit::Comp_FPUComp(u32 op) {
DISABLE;
}
void Jit::Comp_FPU2op(u32 op) {
CONDITIONAL_DISABLE;
int fs = _FS;

View file

@ -141,11 +141,77 @@ void Jit::ApplyPrefixD(const u8 *vregs, u32 prefix, VectorSize sz, bool onlyWrit
static u32 GC_ALIGNED16(ssLoadStoreTemp[1]);
void Jit::Comp_SV(u32 op) {
// DISABLE;
s32 imm = (signed short)(op&0xFFFC);
int vt = ((op >> 16) & 0x1f) | ((op & 3) << 5);
int rs = _RS;
switch (op >> 26)
{
case 50: //lv.s // VI(vt) = Memory::Read_U32(addr);
{
gpr.BindToRegister(rs, true, false);
fpr.MapRegV(vt, MAP_NOINIT);
JitSafeMem safe(this, rs, imm);
safe.SetFar();
OpArg src;
if (safe.PrepareRead(src))
{
MOVSS(fpr.VX(vt), safe.NextFastAddress(0));
}
if (safe.PrepareSlowRead((void *) &Memory::Read_U32))
{
safe.NextSlowRead((void *) &Memory::Read_U32, 0);
MOV(32, M((void *)&ssLoadStoreTemp), R(EAX));
MOVSS(fpr.VX(vt), M((void *)&ssLoadStoreTemp));
}
safe.Finish();
gpr.UnlockAll();
fpr.ReleaseSpillLocks();
}
break;
case 58: //sv.s // Memory::Write_U32(VI(vt), addr);
{
gpr.BindToRegister(rs, true, true);
// Even if we don't use real SIMD there's still 8 or 16 scalar float registers.
fpr.MapRegV(vt, 0);
JitSafeMem safe(this, rs, imm);
safe.SetFar();
OpArg dest;
if (safe.PrepareWrite(dest))
{
MOVSS(safe.NextFastAddress(0), fpr.VX(vt));
}
if (safe.PrepareSlowWrite())
{
MOVSS(M((void *)&ssLoadStoreTemp), fpr.VX(vt));
safe.DoSlowWrite((void *) &Memory::Write_U32, M((void *)&ssLoadStoreTemp), 0);
}
safe.Finish();
fpr.ReleaseSpillLocks();
gpr.UnlockAll();
}
break;
default:
_dbg_assert_msg_(CPU,0,"Trying to interpret instruction that can't be interpreted");
break;
}
}
void Jit::Comp_SVQ(u32 op)
{
int imm = (signed short)(op&0xFFFC);
int rs = _RS;
int vt = (((op >> 16) & 0x1f)) | ((op&1) << 5);
int rs = _RS;
switch (op >> 26)
{
@ -263,5 +329,47 @@ void Jit::Comp_VDot(u32 op) {
js.EatPrefix();
}
void Jit::Comp_Mftv(u32 op) {
int imm = op & 0xFF;
int rt = _RT;
switch ((op >> 21) & 0x1f)
{
case 3: //mfv / mfvc
if (imm < 128) { //R(rt) = VI(imm);
fpr.StoreFromRegisterV(imm);
gpr.BindToRegister(rt, false, true);
MOV(32, gpr.R(rt), fpr.V(imm));
} else if (imm < 128 + VFPU_CTRL_MAX) { //mtvc
gpr.BindToRegister(rt, false, true);
MOV(32, gpr.R(rt), M(&currentMIPS->vfpuCtrl[imm - 128]));
} else if (rt == 0 && imm == 255) {
// This appears to be used as a CPU interlock by some games. Do nothing.
} else {
//ERROR - maybe need to make this value too an "interlock" value?
_dbg_assert_msg_(CPU,0,"mfv - invalid register");
}
break;
case 7: //mtv
if (imm < 128) {
fpr.StoreFromRegisterV(imm);
gpr.BindToRegister(rt, true, false);
MOV(32, fpr.V(imm), gpr.R(rt));
// VI(imm) = R(rt);
} else if (imm < 128 + VFPU_CTRL_MAX) { //mtvc //currentMIPS->vfpuCtrl[imm - 128] = R(rt);
gpr.BindToRegister(rt, true, false);
MOV(32, M(&currentMIPS->vfpuCtrl[imm - 128]), gpr.R(rt));
} else {
//ERROR
_dbg_assert_msg_(CPU,0,"mtv - invalid register");
}
break;
default:
DISABLE;
_dbg_assert_msg_(CPU,0,"Trying to interpret instruction that can't be interpreted");
break;
}
}
}

View file

@ -569,4 +569,6 @@ void Jit::JitSafeMem::Finish()
jit_->SetJumpTarget(skip_);
}
void Jit::Comp_DoNothing(u32 op) { }
} // namespace

View file

@ -118,6 +118,7 @@ public:
void Comp_RelBranchRI(u32 op);
void Comp_FPUBranch(u32 op);
void Comp_FPULS(u32 op);
void Comp_FPUComp(u32 op);
void Comp_Jump(u32 op);
void Comp_JumpReg(u32 op);
void Comp_Syscall(u32 op);
@ -129,15 +130,20 @@ public:
void Comp_Allegrex(u32 op);
void Comp_VBranch(u32 op);
void Comp_MulDivType(u32 op);
void Comp_Special3(u32 op);
void Comp_FPU3op(u32 op);
void Comp_FPU2op(u32 op);
void Comp_mxc1(u32 op);
void Comp_SV(u32 op);
void Comp_SVQ(u32 op);
void Comp_VPFX(u32 op);
void Comp_VDot(u32 op);
void Comp_Mftv(u32 op);
void Comp_DoNothing(u32 op);
void ApplyPrefixST(u8 *vregs, u32 prefix, VectorSize sz);
void ApplyPrefixD(const u8 *vregs, u32 prefix, VectorSize sz, bool onlyWriteMask = false);

View file

@ -59,6 +59,10 @@ void FPURegCache::SpillLockV(int vec, VectorSize sz) {
SpillLockV(v, sz);
}
void FPURegCache::MapRegV(int vreg, int flags) {
BindToRegister(vreg + 32, (flags & MAP_NOINIT) == 0, (flags & MAP_DIRTY) != 0);
}
void FPURegCache::MapRegsV(int vec, VectorSize sz, int flags) {
u8 v[4];
GetVectorRegs(v, sz, vec);

View file

@ -64,6 +64,9 @@ public:
void Start(MIPSState *mips, MIPSAnalyst::AnalysisResults &stats);
void BindToRegister(int preg, bool doLoad = true, bool makeDirty = true);
void StoreFromRegister(int preg);
void StoreFromRegisterV(int preg) {
StoreFromRegister(preg + 32);
}
OpArg GetDefaultLocation(int reg) const;
void SetEmitter(XEmitter *emitter) {emit = emitter;}
@ -94,6 +97,7 @@ public:
void SpillLock(int p1, int p2=0xff, int p3=0xff, int p4=0xff);
void ReleaseSpillLocks();
void MapRegV(int vreg, int flags);
void MapRegsV(int vec, VectorSize vsz, int flags);
void MapRegsV(const u8 *v, VectorSize vsz, int flags);
void SpillLockV(const u8 *v, VectorSize vsz);