Initial VFPU

This commit is contained in:
Henrik Rydgard 2016-05-08 13:32:22 +02:00
parent 98113edbd4
commit 3eb5480ade
3 changed files with 122 additions and 4 deletions

View file

@ -181,7 +181,38 @@ namespace MIPSComp {
}
void IRJit::Comp_SVQ(MIPSOpcode op) {
DISABLE;
int imm = (signed short)(op & 0xFFFC);
int vt = (((op >> 16) & 0x1f)) | ((op & 1) << 5);
MIPSGPReg rs = _RS;
u8 vregs[4];
GetVectorRegs(vregs, V_Quad, vt);
switch (op >> 26) {
case 54: //lv.q
{
// TODO: Add vector load/store instruction to the IR
ir.Write(IROp::LoadFloatV, vregs[0], rs, ir.AddConstant(imm));
ir.Write(IROp::LoadFloatV, vregs[1], rs, ir.AddConstant(imm + 4));
ir.Write(IROp::LoadFloatV, vregs[2], rs, ir.AddConstant(imm + 8));
ir.Write(IROp::LoadFloatV, vregs[3], rs, ir.AddConstant(imm + 12));
}
break;
case 62: //sv.q
{
// CC might be set by slow path below, so load regs first.
ir.Write(IROp::StoreFloatV, vregs[0], rs, ir.AddConstant(imm));
ir.Write(IROp::StoreFloatV, vregs[1], rs, ir.AddConstant(imm + 4));
ir.Write(IROp::StoreFloatV, vregs[2], rs, ir.AddConstant(imm + 8));
ir.Write(IROp::StoreFloatV, vregs[3], rs, ir.AddConstant(imm + 12));
}
break;
default:
DISABLE;
break;
}
}
void IRJit::Comp_VVectorInit(MIPSOpcode op) {
@ -215,6 +246,11 @@ namespace MIPSComp {
}
void IRJit::Comp_VV2Op(MIPSOpcode op) {
CONDITIONAL_DISABLE;
// Pre-processing: Eliminate silly no-op VMOVs, common in Wipeout Pure
if (((op >> 16) & 0x1f) == 0 && _VS == _VD && js.HasNoPrefix()) {
return;
}
DISABLE;
}
@ -231,7 +267,33 @@ namespace MIPSComp {
}
void IRJit::Comp_Mftv(MIPSOpcode op) {
DISABLE;
int imm = op & 0xFF;
MIPSGPReg rt = _RT;
switch ((op >> 21) & 0x1f) {
case 3: //mfv / mfvc
// rt = 0, imm = 255 appears to be used as a CPU interlock by some games.
if (rt != 0) {
if (imm < 128) { //R(rt) = VI(imm);
ir.Write(IROp::VMovToGPR, rt, imm);
logBlocks = 1;
} else {
DISABLE;
}
}
break;
case 7: // mtv
if (imm < 128) {
ir.Write(IROp::VMovFromGPR, imm, rt);
logBlocks = 1;
} else {
DISABLE;
}
break;
default:
DISABLE;
}
}
void IRJit::Comp_Vmfvc(MIPSOpcode op) {

View file

@ -10,6 +10,8 @@
static const IRMeta irMeta[] = {
{ IROp::SetConst, "SetConst", "GC" },
{ IROp::SetConstF, "SetConstF", "FC" },
{ IROp::SetConstV, "SetConstV", "VC" },
{ IROp::Mov, "Mov", "GG" },
{ IROp::Add, "Add", "GGG" },
{ IROp::Sub, "Sub", "GGG" },
@ -62,10 +64,12 @@ static const IRMeta irMeta[] = {
{ IROp::Load16Ext, "Load16Ext", "GGC" },
{ IROp::Load32, "Load32", "GGC" },
{ IROp::LoadFloat, "LoadFloat", "FGC" },
{ IROp::LoadFloatV, "LoadFloatV", "VGC" },
{ IROp::Store8, "Store8", "GGC" },
{ IROp::Store16, "Store16", "GGC" },
{ IROp::Store32, "Store32", "GGC" },
{ IROp::StoreFloat, "StoreFloat", "FGC" },
{ IROp::StoreFloatV, "StoreFloatV", "VGC" },
{ IROp::FAdd, "FAdd", "FFF" },
{ IROp::FSub, "FSub", "FFF" },
{ IROp::FMul, "FMul", "FFF" },
@ -82,6 +86,8 @@ static const IRMeta irMeta[] = {
{ IROp::FCvtSW, "FCvtSW", "FF" },
{ IROp::FMovFromGPR, "FMovFromGPR", "FG" },
{ IROp::FMovToGPR, "FMovToGPR", "GF" },
{ IROp::VMovFromGPR, "VMovFromGPR", "VG" },
{ IROp::VMovToGPR, "VMovToGPR", "GV" },
{ IROp::FpCondToReg, "FpCondToReg", "G" },
{ IROp::VfpuCtrlToReg, "VfpuCtrlToReg", "GI" },
{ IROp::SetCtrlVFPU, "SetCtrlVFPU", "TC" },
@ -117,6 +123,12 @@ u32 IRInterpret(MIPSState *mips, const IRInst *inst, const u32 *constPool, int c
case IROp::SetConst:
mips->r[inst->dest] = constPool[inst->src1];
break;
case IROp::SetConstF:
memcpy(&mips->f[inst->dest], &constPool[inst->src1], 4);
break;
case IROp::SetConstV:
memcpy(&mips->f[inst->dest], &constPool[inst->src1], 4);
break;
case IROp::Add:
mips->r[inst->dest] = mips->r[inst->src1] + mips->r[inst->src2];
break;
@ -181,6 +193,9 @@ u32 IRInterpret(MIPSState *mips, const IRInst *inst, const u32 *constPool, int c
case IROp::LoadFloat:
mips->f[inst->dest] = Memory::ReadUnchecked_Float(mips->r[inst->src1] + constPool[inst->src2]);
break;
case IROp::LoadFloatV:
mips->v[voffset[inst->dest]] = Memory::ReadUnchecked_Float(mips->r[inst->src1] + constPool[inst->src2]);
break;
case IROp::Store8:
Memory::WriteUnchecked_U8(mips->r[inst->src3], mips->r[inst->src1] + constPool[inst->src2]);
@ -194,6 +209,9 @@ u32 IRInterpret(MIPSState *mips, const IRInst *inst, const u32 *constPool, int c
case IROp::StoreFloat:
Memory::WriteUnchecked_Float(mips->f[inst->src3], mips->r[inst->src1] + constPool[inst->src2]);
break;
case IROp::StoreFloatV:
Memory::WriteUnchecked_Float(mips->v[voffset[inst->src3]], mips->r[inst->src1] + constPool[inst->src2]);
break;
case IROp::ShlImm:
mips->r[inst->dest] = mips->r[inst->src1] << (int)inst->src2;
@ -389,6 +407,7 @@ u32 IRInterpret(MIPSState *mips, const IRInst *inst, const u32 *constPool, int c
}
break; //cvt.w.s
}
case IROp::ZeroFpCond:
mips->fpcond = 0;
break;
@ -400,6 +419,13 @@ u32 IRInterpret(MIPSState *mips, const IRInst *inst, const u32 *constPool, int c
memcpy(&mips->r[inst->dest], &mips->f[inst->src1], 4);
break;
case IROp::VMovFromGPR:
memcpy(&mips->v[voffset[inst->dest]], &mips->r[inst->src1], 4);
break;
case IROp::VMovToGPR:
memcpy(&mips->r[inst->dest], &mips->v[voffset[inst->src1]], 4);
break;
case IROp::ExitToConst:
return constPool[inst->dest];
@ -540,12 +566,31 @@ const char *GetGPRName(int r) {
}
void DisassembleParam(char *buf, int bufSize, u8 param, char type, const u32 *constPool) {
static const char *vfpuCtrlNames[VFPU_CTRL_MAX] = {
"SPFX",
"TPFX",
"DPFX",
"CC",
"INF4",
"RSV5",
"RSV6",
"REV",
"RCX0",
"RCX1",
"RCX2",
"RCX3",
"RCX4",
"RCX5",
"RCX6",
"RCX7",
};
switch (type) {
case 'G':
snprintf(buf, bufSize, "%s", GetGPRName(param));
break;
case 'F':
snprintf(buf, bufSize, "r%d", param);
snprintf(buf, bufSize, "f%d", param);
break;
case 'C':
snprintf(buf, bufSize, "%08x", constPool[param]);
@ -553,6 +598,12 @@ void DisassembleParam(char *buf, int bufSize, u8 param, char type, const u32 *co
case 'I':
snprintf(buf, bufSize, "%02x", param);
break;
case 'V':
snprintf(buf, bufSize, "v%d", param);
break;
case 'T':
snprintf(buf, bufSize, "%s", vfpuCtrlNames[param]);
break;
case '_':
case '\0':
buf[0] = 0;

View file

@ -17,7 +17,8 @@
enum class IROp : u8 {
SetConst,
FSetConst,
SetConstF,
SetConstV,
Mov,
@ -88,11 +89,13 @@ enum class IROp : u8 {
Load16Ext,
Load32,
LoadFloat,
LoadFloatV,
Store8,
Store16,
Store32,
StoreFloat,
StoreFloatV,
Ext8to32,
Ext16to32,
@ -136,6 +139,8 @@ enum class IROp : u8 {
UpdateRoundingMode,
SetCtrlVFPU,
VMovFromGPR,
VMovToGPR,
// Fake/System instructions
Interpret,