From 16bc3c00867113ec627cb092cf3381e5e8b3cf9b Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 24 Feb 2019 11:14:34 -0800 Subject: [PATCH] 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. --- Core/MIPS/MIPSIntVFPU.cpp | 41 ++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/Core/MIPS/MIPSIntVFPU.cpp b/Core/MIPS/MIPSIntVFPU.cpp index e42e81e86c..d67ebd183c 100644 --- a/Core/MIPS/MIPSIntVFPU.cpp +++ b/Core/MIPS/MIPSIntVFPU.cpp @@ -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;