interp: Implement vcrs prefixes and sizes.

It only makes sense as triple, but it can be used as quad/single/etc. and
has consistent and sane results.
This commit is contained in:
Unknown W. Brackets committed 2019-03-30 12:26:09 -07:00
1 parent ceeaf3b7ef
commit 16bc3c0086
1 file changed
+19 -22
+19 -22
View File
@@ -103,7 +103,7 @@ void ApplyPrefixST(float *r, u32 data, VectorSize size)
return;
int n = GetNumVectorElements(size);
float origV[4];
float origV[4]{};
static const float constantArray[8] = {0.f, 1.f, 2.f, 0.5f, 3.f, 1.f/3.f, 0.25f, 1.f/6.f};
for (int i = 0; i < n; i++)
@@ -120,16 +120,6 @@ void ApplyPrefixST(float *r, u32 data, VectorSize size)
if (!constants)
{
// Prefix may say "z, z, z, z" but if this is a pair, we force to x.
// TODO: But some ops seem to use const 0 instead?
if (regnum >= n) {
ERROR_LOG_REPORT(CPU, "Invalid VFPU swizzle: %08x: %i / %d at PC = %08x (%s)", data, regnum, n, currentMIPS->pc, MIPSDisasmAt(currentMIPS->pc));
//for (int i = 0; i < 12; i++) {
// ERROR_LOG(CPU, " vfpuCtrl[%i] = %08x", i, currentMIPS->vfpuCtrl[i]);
//}
regnum = 0;
}
r[i] = origV[regnum];
if (abs)
r[i] = fabs(r[i]);
@@ -1189,24 +1179,31 @@ namespace MIPSInt
EatPrefixes();
}
void Int_Vcrs(MIPSOpcode op)
{
void Int_Vcrs(MIPSOpcode op) {
//half a cross product
float s[4], t[4];
float d[4];
float s[4]{}, t[4]{}, d[4];
int vd = _VD;
int vs = _VS;
int vt = _VT;
VectorSize sz = GetVecSize(op);
if (sz != V_Triple)
_dbg_assert_msg_(CPU,0,"Trying to interpret instruction that can't be interpreted");
ReadVector(s, sz, vs);
ReadVector(t, sz, vt);
// no swizzles allowed
d[0] = s[1] * t[2];
d[1] = s[2] * t[0];
d[2] = s[0] * t[1];
// S prefix forces swizzle (yzx?.)
// That means negate still works, but constants are a bit weird.
u32 sprefixRemove = VFPU_SWIZZLE(3, 3, 3, 0);
u32 sprefixAdd = VFPU_SWIZZLE(1, 2, 0, 0);
ApplyPrefixST(s, VFPURewritePrefix(VFPU_CTRL_SPREFIX, sprefixRemove, sprefixAdd), sz);
// T prefix forces swizzle (zxy?.)
u32 tprefixRemove = VFPU_SWIZZLE(3, 3, 3, 0);
u32 tprefixAdd = VFPU_SWIZZLE(2, 0, 1, 0);
ApplyPrefixST(t, VFPURewritePrefix(VFPU_CTRL_TPREFIX, tprefixRemove, tprefixAdd), sz);
d[0] = s[0] * t[0];
d[1] = s[1] * t[1];
d[2] = s[2] * t[2];
d[3] = s[3] * t[3];
ApplyPrefixD(d, sz);
WriteVector(d, sz, vd);
PC += 4;