mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Initial VFPU
This commit is contained in:
parent
98113edbd4
commit
3eb5480ade
3 changed files with 122 additions and 4 deletions
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Reference in a new issue