mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-23 03:09:10 +02:00
Merge pull request #11956 from unknownbrackets/vfpu-chunk7
Correct vmfvc/vmtvc decoding, prefixes on vsgn, vdot, vhdp, and matrix init
This commit is contained in:
5 files changed
+154
-94
No files matched your search
@@ -1334,17 +1334,20 @@ namespace MIPSComp
|
||||
CONDITIONAL_DISABLE(VFPU_XFER);
|
||||
|
||||
int vd = _VD;
|
||||
int imm = (op >> 8) & 0xFF;
|
||||
if (imm >= 128 && imm < 128 + VFPU_CTRL_MAX) {
|
||||
int imm = (op >> 8) & 0x7F;
|
||||
if (imm < VFPU_CTRL_MAX) {
|
||||
fpr.MapRegV(vd);
|
||||
if (imm - 128 == VFPU_CTRL_CC) {
|
||||
if (imm == VFPU_CTRL_CC) {
|
||||
gpr.MapReg(MIPS_REG_VFPUCC, 0);
|
||||
VMOV(fpr.V(vd), gpr.R(MIPS_REG_VFPUCC));
|
||||
} else {
|
||||
ADDI2R(SCRATCHREG1, CTXREG, offsetof(MIPSState, vfpuCtrl[0]) + (imm - 128) * 4, SCRATCHREG2);
|
||||
ADDI2R(SCRATCHREG1, CTXREG, offsetof(MIPSState, vfpuCtrl[0]) + imm * 4, SCRATCHREG2);
|
||||
VLDR(fpr.V(vd), SCRATCHREG1, 0);
|
||||
}
|
||||
fpr.ReleaseSpillLocksAndDiscardTemps();
|
||||
} else {
|
||||
fpr.MapRegV(vd);
|
||||
MOVI2F(fpr.V(vd), 0.0f, SCRATCHREG1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1353,23 +1356,23 @@ namespace MIPSComp
|
||||
CONDITIONAL_DISABLE(VFPU_XFER);
|
||||
|
||||
int vs = _VS;
|
||||
int imm = op & 0xFF;
|
||||
if (imm >= 128 && imm < 128 + VFPU_CTRL_MAX) {
|
||||
int imm = op & 0x7F;
|
||||
if (imm < VFPU_CTRL_MAX) {
|
||||
fpr.MapRegV(vs);
|
||||
if (imm - 128 == VFPU_CTRL_CC) {
|
||||
if (imm == VFPU_CTRL_CC) {
|
||||
gpr.MapReg(MIPS_REG_VFPUCC, MAP_DIRTY | MAP_NOINIT);
|
||||
VMOV(gpr.R(MIPS_REG_VFPUCC), fpr.V(vs));
|
||||
} else {
|
||||
ADDI2R(SCRATCHREG1, CTXREG, offsetof(MIPSState, vfpuCtrl[0]) + (imm - 128) * 4, SCRATCHREG2);
|
||||
ADDI2R(SCRATCHREG1, CTXREG, offsetof(MIPSState, vfpuCtrl[0]) + imm * 4, SCRATCHREG2);
|
||||
VSTR(fpr.V(vs), SCRATCHREG1, 0);
|
||||
}
|
||||
fpr.ReleaseSpillLocksAndDiscardTemps();
|
||||
|
||||
if (imm - 128 == VFPU_CTRL_SPREFIX) {
|
||||
if (imm == VFPU_CTRL_SPREFIX) {
|
||||
js.prefixSFlag = JitState::PREFIX_UNKNOWN;
|
||||
} else if (imm - 128 == VFPU_CTRL_TPREFIX) {
|
||||
} else if (imm == VFPU_CTRL_TPREFIX) {
|
||||
js.prefixTFlag = JitState::PREFIX_UNKNOWN;
|
||||
} else if (imm - 128 == VFPU_CTRL_DPREFIX) {
|
||||
} else if (imm == VFPU_CTRL_DPREFIX) {
|
||||
js.prefixDFlag = JitState::PREFIX_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1067,17 +1067,20 @@ namespace MIPSComp {
|
||||
CONDITIONAL_DISABLE(VFPU_XFER);
|
||||
|
||||
int vd = _VD;
|
||||
int imm = (op >> 8) & 0xFF;
|
||||
if (imm >= 128 && imm < 128 + VFPU_CTRL_MAX) {
|
||||
int imm = (op >> 8) & 0x7F;
|
||||
if (imm < VFPU_CTRL_MAX) {
|
||||
fpr.MapRegV(vd);
|
||||
if (imm - 128 == VFPU_CTRL_CC) {
|
||||
if (imm == VFPU_CTRL_CC) {
|
||||
gpr.MapReg(MIPS_REG_VFPUCC, 0);
|
||||
fp.FMOV(fpr.V(vd), gpr.R(MIPS_REG_VFPUCC));
|
||||
} else {
|
||||
ADDI2R(SCRATCH1_64, CTXREG, offsetof(MIPSState, vfpuCtrl[0]) + (imm - 128) * 4, SCRATCH2);
|
||||
ADDI2R(SCRATCH1_64, CTXREG, offsetof(MIPSState, vfpuCtrl[0]) + imm * 4, SCRATCH2);
|
||||
fp.LDR(32, INDEX_UNSIGNED, fpr.V(vd), SCRATCH1_64, 0);
|
||||
}
|
||||
fpr.ReleaseSpillLocksAndDiscardTemps();
|
||||
} else {
|
||||
fpr.MapRegV(vd);
|
||||
fp.MOVI2F(fpr.V(vd), 0.0f, SCRATCH1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1085,23 +1088,23 @@ namespace MIPSComp {
|
||||
CONDITIONAL_DISABLE(VFPU_XFER);
|
||||
|
||||
int vs = _VS;
|
||||
int imm = op & 0xFF;
|
||||
if (imm >= 128 && imm < 128 + VFPU_CTRL_MAX) {
|
||||
int imm = op & 0x7F;
|
||||
if (imm < VFPU_CTRL_MAX) {
|
||||
fpr.MapRegV(vs);
|
||||
if (imm - 128 == VFPU_CTRL_CC) {
|
||||
if (imm == VFPU_CTRL_CC) {
|
||||
gpr.MapReg(MIPS_REG_VFPUCC, MAP_DIRTY | MAP_NOINIT);
|
||||
fp.FMOV(gpr.R(MIPS_REG_VFPUCC), fpr.V(vs));
|
||||
} else {
|
||||
ADDI2R(SCRATCH1_64, CTXREG, offsetof(MIPSState, vfpuCtrl[0]) + (imm - 128) * 4, SCRATCH2);
|
||||
ADDI2R(SCRATCH1_64, CTXREG, offsetof(MIPSState, vfpuCtrl[0]) + imm * 4, SCRATCH2);
|
||||
fp.STR(32, INDEX_UNSIGNED, fpr.V(vs), SCRATCH1_64, 0);
|
||||
}
|
||||
fpr.ReleaseSpillLocksAndDiscardTemps();
|
||||
|
||||
if (imm - 128 == VFPU_CTRL_SPREFIX) {
|
||||
if (imm == VFPU_CTRL_SPREFIX) {
|
||||
js.prefixSFlag = JitState::PREFIX_UNKNOWN;
|
||||
} else if (imm - 128 == VFPU_CTRL_TPREFIX) {
|
||||
} else if (imm == VFPU_CTRL_TPREFIX) {
|
||||
js.prefixTFlag = JitState::PREFIX_UNKNOWN;
|
||||
} else if (imm - 128 == VFPU_CTRL_DPREFIX) {
|
||||
} else if (imm == VFPU_CTRL_DPREFIX) {
|
||||
js.prefixDFlag = JitState::PREFIX_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
+14
-14
@@ -426,11 +426,11 @@ namespace MIPSComp {
|
||||
void IRFrontend::Comp_VMatrixInit(MIPSOpcode op) {
|
||||
CONDITIONAL_DISABLE(VFPU_XFER);
|
||||
MatrixSize sz = GetMtxSize(op);
|
||||
if (sz != M_4x4) {
|
||||
if (sz != M_4x4 || !js.HasNoPrefix()) {
|
||||
DISABLE;
|
||||
}
|
||||
|
||||
// Matrix init (no prefixes)
|
||||
// Matrix init (weird prefixes)
|
||||
// d[N,M] = CONST[N,M]
|
||||
|
||||
// Not really about trying here, it will work if enabled.
|
||||
@@ -960,7 +960,7 @@ namespace MIPSComp {
|
||||
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.
|
||||
// rt = 0, imm = 255 appears to be used as a CPU interlock by some games.
|
||||
if (rt != MIPS_REG_ZERO) {
|
||||
if (imm < 128) { //R(rt) = VI(imm);
|
||||
ir.Write(IROp::FMovToGPR, rt, vfpuBase + voffset[imm]);
|
||||
@@ -1021,9 +1021,9 @@ namespace MIPSComp {
|
||||
// D[0] = VFPU_CTRL[i]
|
||||
|
||||
int vd = _VD;
|
||||
int imm = (op >> 8) & 0xFF;
|
||||
if (imm >= 128 && imm < 128 + VFPU_CTRL_MAX) {
|
||||
ir.Write(IROp::VfpuCtrlToReg, IRTEMP_0, imm - 128);
|
||||
int imm = (op >> 8) & 0x7F;
|
||||
if (imm < VFPU_CTRL_MAX) {
|
||||
ir.Write(IROp::VfpuCtrlToReg, IRTEMP_0, imm);
|
||||
ir.Write(IROp::FMovFromGPR, vfpuBase + voffset[vd], IRTEMP_0);
|
||||
} else {
|
||||
INVALIDOP;
|
||||
@@ -1038,22 +1038,22 @@ namespace MIPSComp {
|
||||
|
||||
int vs = _VS;
|
||||
int imm = op & 0xFF;
|
||||
if (imm >= 128 && imm < 128 + VFPU_CTRL_MAX) {
|
||||
if (imm < VFPU_CTRL_MAX) {
|
||||
u32 mask;
|
||||
if (GetVFPUCtrlMask(imm - 128, &mask)) {
|
||||
if (GetVFPUCtrlMask(imm, &mask)) {
|
||||
if (mask != 0xFFFFFFFF) {
|
||||
ir.Write(IROp::FMovToGPR, IRTEMP_0, vfpuBase + voffset[imm]);
|
||||
ir.Write(IROp::AndConst, IRTEMP_0, IRTEMP_0, ir.AddConstant(mask));
|
||||
ir.Write(IROp::SetCtrlVFPUReg, imm - 128, IRTEMP_0);
|
||||
ir.Write(IROp::SetCtrlVFPUReg, imm, IRTEMP_0);
|
||||
} else {
|
||||
ir.Write(IROp::SetCtrlVFPUFReg, imm - 128, vfpuBase + voffset[vs]);
|
||||
ir.Write(IROp::SetCtrlVFPUFReg, imm, vfpuBase + voffset[vs]);
|
||||
}
|
||||
}
|
||||
if (imm - 128 == VFPU_CTRL_SPREFIX) {
|
||||
if (imm == VFPU_CTRL_SPREFIX) {
|
||||
js.prefixSFlag = JitState::PREFIX_UNKNOWN;
|
||||
} else if (imm - 128 == VFPU_CTRL_TPREFIX) {
|
||||
} else if (imm == VFPU_CTRL_TPREFIX) {
|
||||
js.prefixTFlag = JitState::PREFIX_UNKNOWN;
|
||||
} else if (imm - 128 == VFPU_CTRL_DPREFIX) {
|
||||
} else if (imm == VFPU_CTRL_DPREFIX) {
|
||||
js.prefixDFlag = JitState::PREFIX_UNKNOWN;
|
||||
}
|
||||
} else {
|
||||
@@ -1869,7 +1869,7 @@ namespace MIPSComp {
|
||||
|
||||
void IRFrontend::Comp_Vsgn(MIPSOpcode op) {
|
||||
CONDITIONAL_DISABLE(VFPU_VEC);
|
||||
if (js.HasUnknownPrefix()) {
|
||||
if (js.HasUnknownPrefix() || !IsPrefixWithinSize(js.prefixS, op) || !IsPrefixWithinSize(js.prefixT, op)) {
|
||||
DISABLE;
|
||||
}
|
||||
|
||||
|
||||
+97
-47
@@ -317,24 +317,20 @@ namespace MIPSInt
|
||||
PC += 4;
|
||||
}
|
||||
|
||||
void Int_VMatrixInit(MIPSOpcode op)
|
||||
{
|
||||
static const float idt[16] =
|
||||
{
|
||||
void Int_VMatrixInit(MIPSOpcode op) {
|
||||
static const float idt[16] = {
|
||||
1,0,0,0,
|
||||
0,1,0,0,
|
||||
0,0,1,0,
|
||||
0,0,0,1,
|
||||
};
|
||||
static const float zero[16] =
|
||||
{
|
||||
static const float zero[16] = {
|
||||
0,0,0,0,
|
||||
0,0,0,0,
|
||||
0,0,0,0,
|
||||
0,0,0,0,
|
||||
};
|
||||
static const float one[16] =
|
||||
{
|
||||
static const float one[16] = {
|
||||
1,1,1,1,
|
||||
1,1,1,1,
|
||||
1,1,1,1,
|
||||
@@ -344,8 +340,7 @@ namespace MIPSInt
|
||||
MatrixSize sz = GetMtxSize(op);
|
||||
const float *m;
|
||||
|
||||
switch ((op >> 16) & 0xF)
|
||||
{
|
||||
switch ((op >> 16) & 0xF) {
|
||||
case 3: m=idt; break; //identity // vmidt
|
||||
case 6: m=zero; break; // vmzero
|
||||
case 7: m=one; break; // vmone
|
||||
@@ -356,7 +351,37 @@ namespace MIPSInt
|
||||
return;
|
||||
}
|
||||
|
||||
WriteMatrix(m, sz, vd);
|
||||
// The S prefix generates constants, but only for the final (possibly transposed) row.
|
||||
if (currentMIPS->vfpuCtrl[VFPU_CTRL_SPREFIX] & 0xF0F00) {
|
||||
float prefixed[16];
|
||||
memcpy(prefixed, m, sizeof(prefixed));
|
||||
|
||||
int off = GetMatrixSide(sz) - 1;
|
||||
u32 sprefixRemove = VFPU_ANY_SWIZZLE();
|
||||
u32 sprefixAdd;
|
||||
switch ((op >> 16) & 0xF) {
|
||||
case 3:
|
||||
{
|
||||
VFPUConst constX = off == 0 ? VFPUConst::ONE : VFPUConst::ZERO;
|
||||
VFPUConst constY = off == 1 ? VFPUConst::ONE : VFPUConst::ZERO;
|
||||
VFPUConst constZ = off == 2 ? VFPUConst::ONE : VFPUConst::ZERO;
|
||||
VFPUConst constW = off == 3 ? VFPUConst::ONE : VFPUConst::ZERO;
|
||||
sprefixAdd = VFPU_MAKE_CONSTANTS(constX, constY, constZ, constW);
|
||||
break;
|
||||
}
|
||||
case 6:
|
||||
sprefixAdd = VFPU_MAKE_CONSTANTS(VFPUConst::ZERO, VFPUConst::ZERO, VFPUConst::ZERO, VFPUConst::ZERO);
|
||||
break;
|
||||
case 7:
|
||||
sprefixAdd = VFPU_MAKE_CONSTANTS(VFPUConst::ONE, VFPUConst::ONE, VFPUConst::ONE, VFPUConst::ONE);
|
||||
break;
|
||||
}
|
||||
ApplyPrefixST(&prefixed[off * 4], VFPURewritePrefix(VFPU_CTRL_SPREFIX, sprefixRemove, sprefixAdd), V_Quad);
|
||||
WriteMatrix(prefixed, sz, vd);
|
||||
} else {
|
||||
// Write mask applies to the final (maybe transposed) row. Sat causes hang.
|
||||
WriteMatrix(m, sz, vd);
|
||||
}
|
||||
PC += 4;
|
||||
EatPrefixes();
|
||||
}
|
||||
@@ -642,19 +667,30 @@ namespace MIPSInt
|
||||
EatPrefixes();
|
||||
}
|
||||
|
||||
void Int_Vsgn(MIPSOpcode op)
|
||||
{
|
||||
float s[4], d[4];
|
||||
void Int_Vsgn(MIPSOpcode op) {
|
||||
float s[4], t[4], d[4];
|
||||
int vd = _VD;
|
||||
int vs = _VS;
|
||||
VectorSize sz = GetVecSize(op);
|
||||
ReadVector(s, sz, vs);
|
||||
ApplySwizzleS(s, sz);
|
||||
for (int i = 0; i < GetNumVectorElements(sz); i++)
|
||||
{
|
||||
|
||||
// Not sure who would do this, but using abs/neg allows a compare against 3 or -3.
|
||||
u32 tprefixRemove = VFPU_ANY_SWIZZLE();
|
||||
u32 tprefixAdd = VFPU_MAKE_CONSTANTS(VFPUConst::ZERO, VFPUConst::ZERO, VFPUConst::ZERO, VFPUConst::ZERO);
|
||||
ApplyPrefixST(t, VFPURewritePrefix(VFPU_CTRL_TPREFIX, tprefixRemove, tprefixAdd), sz);
|
||||
|
||||
int n = GetNumVectorElements(sz);
|
||||
if (n < 4) {
|
||||
// Compare with a swizzled value out of bounds always produces 0.
|
||||
memcpy(&s[n], &t[n], sizeof(float) * (4 - n));
|
||||
}
|
||||
ApplySwizzleS(s, V_Quad);
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
float diff = s[i] - t[i];
|
||||
// To handle NaNs correctly, we do this with integer hackery
|
||||
u32 val;
|
||||
memcpy(&val, &s[i], sizeof(u32));
|
||||
memcpy(&val, &diff, sizeof(u32));
|
||||
if (val == 0 || val == 0x80000000)
|
||||
d[i] = 0.0f;
|
||||
else if ((val >> 31) == 0)
|
||||
@@ -1029,51 +1065,63 @@ namespace MIPSInt
|
||||
EatPrefixes();
|
||||
}
|
||||
|
||||
void Int_VDot(MIPSOpcode op)
|
||||
{
|
||||
float s[4], t[4];
|
||||
void Int_VDot(MIPSOpcode op) {
|
||||
float s[4]{}, t[4]{};
|
||||
float d;
|
||||
int vd = _VD;
|
||||
int vs = _VS;
|
||||
int vt = _VT;
|
||||
VectorSize sz = GetVecSize(op);
|
||||
ReadVector(s, sz, vs);
|
||||
ApplySwizzleS(s, sz);
|
||||
ApplySwizzleS(s, V_Quad);
|
||||
ReadVector(t, sz, vt);
|
||||
ApplySwizzleT(t, sz);
|
||||
float sum = 0.0f;
|
||||
int n = GetNumVectorElements(sz);
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
sum += s[i]*t[i];
|
||||
ApplySwizzleT(t, V_Quad);
|
||||
d = 0.0f;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
d += s[i] * t[i];
|
||||
}
|
||||
d = sum;
|
||||
ApplyPrefixD(&d,V_Single);
|
||||
ApplyPrefixD(&d, V_Single);
|
||||
WriteVector(&d, V_Single, vd);
|
||||
PC += 4;
|
||||
EatPrefixes();
|
||||
}
|
||||
|
||||
void Int_VHdp(MIPSOpcode op)
|
||||
{
|
||||
float s[4], t[4];
|
||||
void Int_VHdp(MIPSOpcode op) {
|
||||
float s[4]{}, t[4]{};
|
||||
float d;
|
||||
int vd = _VD;
|
||||
int vs = _VS;
|
||||
int vt = _VT;
|
||||
VectorSize sz = GetVecSize(op);
|
||||
ReadVector(s, sz, vs);
|
||||
ApplySwizzleS(s, sz);
|
||||
ReadVector(t, sz, vt);
|
||||
ApplySwizzleT(t, sz);
|
||||
ApplySwizzleT(t, V_Quad);
|
||||
|
||||
// S prefix forces constant 1 for the last element (w for quad.)
|
||||
// Otherwise it is the same as vdot.
|
||||
u32 sprefixRemove;
|
||||
u32 sprefixAdd;
|
||||
if (sz == V_Quad) {
|
||||
sprefixRemove = VFPU_SWIZZLE(0, 0, 0, 3);
|
||||
sprefixAdd = VFPU_MAKE_CONSTANTS(VFPUConst::NONE, VFPUConst::NONE, VFPUConst::NONE, VFPUConst::ONE);
|
||||
} else if (sz == V_Triple) {
|
||||
sprefixRemove = VFPU_SWIZZLE(0, 0, 3, 0);
|
||||
sprefixAdd = VFPU_MAKE_CONSTANTS(VFPUConst::NONE, VFPUConst::NONE, VFPUConst::ONE, VFPUConst::NONE);
|
||||
} else if (sz == V_Pair) {
|
||||
sprefixRemove = VFPU_SWIZZLE(0, 3, 0, 0);
|
||||
sprefixAdd = VFPU_MAKE_CONSTANTS(VFPUConst::NONE, VFPUConst::ONE, VFPUConst::NONE, VFPUConst::NONE);
|
||||
} else {
|
||||
sprefixRemove = VFPU_SWIZZLE(3, 0, 0, 0);
|
||||
sprefixAdd = VFPU_MAKE_CONSTANTS(VFPUConst::ONE, VFPUConst::NONE, VFPUConst::NONE, VFPUConst::NONE);
|
||||
}
|
||||
ApplyPrefixST(s, VFPURewritePrefix(VFPU_CTRL_SPREFIX, sprefixRemove, sprefixAdd), V_Quad);
|
||||
|
||||
float sum = 0.0f;
|
||||
int n = GetNumVectorElements(sz);
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
sum += (i == n - 1) ? t[i] : s[i]*t[i];
|
||||
for (int i = 0; i < 4; i++) {
|
||||
sum += s[i] * t[i];
|
||||
}
|
||||
d = my_isnan(sum) ? fabsf(sum) : sum;
|
||||
ApplyPrefixD(&d,V_Single);
|
||||
ApplyPrefixD(&d, V_Single);
|
||||
WriteVector(&d, V_Single, vd);
|
||||
PC += 4;
|
||||
EatPrefixes();
|
||||
@@ -1549,20 +1597,22 @@ namespace MIPSInt
|
||||
|
||||
void Int_Vmfvc(MIPSOpcode op) {
|
||||
int vd = _VD;
|
||||
int imm = (op >> 8) & 0xFF;
|
||||
if (imm >= 128 && imm < 128 + VFPU_CTRL_MAX) {
|
||||
VI(vd) = currentMIPS->vfpuCtrl[imm - 128];
|
||||
int imm = (op >> 8) & 0x7F;
|
||||
if (imm < VFPU_CTRL_MAX) {
|
||||
VI(vd) = currentMIPS->vfpuCtrl[imm];
|
||||
} else {
|
||||
VI(vd) = 0;
|
||||
}
|
||||
PC += 4;
|
||||
}
|
||||
|
||||
void Int_Vmtvc(MIPSOpcode op) {
|
||||
int vs = _VS;
|
||||
int imm = op & 0xFF;
|
||||
if (imm >= 128 && imm < 128 + VFPU_CTRL_MAX) {
|
||||
int imm = op & 0x7F;
|
||||
if (imm < VFPU_CTRL_MAX) {
|
||||
u32 mask;
|
||||
if (GetVFPUCtrlMask(imm - 128, &mask)) {
|
||||
currentMIPS->vfpuCtrl[imm - 128] = VI(vs) & mask;
|
||||
if (GetVFPUCtrlMask(imm, &mask)) {
|
||||
currentMIPS->vfpuCtrl[imm] = VI(vs) & mask;
|
||||
}
|
||||
}
|
||||
PC += 4;
|
||||
|
||||
+15
-11
@@ -2529,38 +2529,42 @@ void Jit::Comp_Mftv(MIPSOpcode op) {
|
||||
void Jit::Comp_Vmfvc(MIPSOpcode op) {
|
||||
CONDITIONAL_DISABLE(VFPU_XFER);
|
||||
int vd = _VD;
|
||||
int imm = (op >> 8) & 0xFF;
|
||||
if (imm >= 128 && imm < 128 + VFPU_CTRL_MAX) {
|
||||
int imm = (op >> 8) & 0x7F;
|
||||
if (imm < VFPU_CTRL_MAX) {
|
||||
fpr.MapRegV(vd, MAP_DIRTY | MAP_NOINIT);
|
||||
if (imm - 128 == VFPU_CTRL_CC) {
|
||||
if (imm == VFPU_CTRL_CC) {
|
||||
gpr.MapReg(MIPS_REG_VFPUCC, true, false);
|
||||
MOVD_xmm(fpr.VX(vd), gpr.R(MIPS_REG_VFPUCC));
|
||||
} else {
|
||||
MOVSS(fpr.VX(vd), MIPSSTATE_VAR_ELEM32(vfpuCtrl[0], imm - 128));
|
||||
MOVSS(fpr.VX(vd), MIPSSTATE_VAR_ELEM32(vfpuCtrl[0], imm));
|
||||
}
|
||||
fpr.ReleaseSpillLocks();
|
||||
} else {
|
||||
fpr.MapRegV(vd, MAP_DIRTY | MAP_NOINIT);
|
||||
XORPS(fpr.VX(vd), fpr.V(vd));
|
||||
fpr.ReleaseSpillLocks();
|
||||
}
|
||||
}
|
||||
|
||||
void Jit::Comp_Vmtvc(MIPSOpcode op) {
|
||||
CONDITIONAL_DISABLE(VFPU_XFER);
|
||||
int vs = _VS;
|
||||
int imm = op & 0xFF;
|
||||
if (imm >= 128 && imm < 128 + VFPU_CTRL_MAX) {
|
||||
int imm = op & 0x7F;
|
||||
if (imm < VFPU_CTRL_MAX) {
|
||||
fpr.MapRegV(vs, 0);
|
||||
if (imm - 128 == VFPU_CTRL_CC) {
|
||||
if (imm == VFPU_CTRL_CC) {
|
||||
gpr.MapReg(MIPS_REG_VFPUCC, false, true);
|
||||
MOVD_xmm(gpr.R(MIPS_REG_VFPUCC), fpr.VX(vs));
|
||||
} else {
|
||||
MOVSS(MIPSSTATE_VAR_ELEM32(vfpuCtrl[0], imm - 128), fpr.VX(vs));
|
||||
MOVSS(MIPSSTATE_VAR_ELEM32(vfpuCtrl[0], imm), fpr.VX(vs));
|
||||
}
|
||||
fpr.ReleaseSpillLocks();
|
||||
|
||||
if (imm - 128 == VFPU_CTRL_SPREFIX) {
|
||||
if (imm == VFPU_CTRL_SPREFIX) {
|
||||
js.prefixSFlag = JitState::PREFIX_UNKNOWN;
|
||||
} else if (imm - 128 == VFPU_CTRL_TPREFIX) {
|
||||
} else if (imm == VFPU_CTRL_TPREFIX) {
|
||||
js.prefixTFlag = JitState::PREFIX_UNKNOWN;
|
||||
} else if (imm - 128 == VFPU_CTRL_DPREFIX) {
|
||||
} else if (imm == VFPU_CTRL_DPREFIX) {
|
||||
js.prefixDFlag = JitState::PREFIX_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user