From 442d6450bb13ec6282395161075c54849bfc7fe7 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 24 Feb 2019 16:44:51 -0800 Subject: [PATCH] interp: Correct prefixes on vfad and vavg. Including write mask, which didn't work before. --- Core/MIPS/MIPSIntVFPU.cpp | 60 ++++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 23 deletions(-) diff --git a/Core/MIPS/MIPSIntVFPU.cpp b/Core/MIPS/MIPSIntVFPU.cpp index b4fc2fea5c..9b782a45ad 100644 --- a/Core/MIPS/MIPSIntVFPU.cpp +++ b/Core/MIPS/MIPSIntVFPU.cpp @@ -1390,46 +1390,60 @@ namespace MIPSInt EatPrefixes(); } - void Int_Vfad(MIPSOpcode op) - { - float s[4]; + void Int_Vfad(MIPSOpcode op) { + float s[4]{}, t[4]{}; float d; int vd = _VD; int vs = _VS; VectorSize sz = GetVecSize(op); ReadVector(s, sz, vs); - ApplySwizzleS(s, sz); - float sum = 0.0f; - int n = GetNumVectorElements(sz); - for (int i = 0; i < n; i++) - { - sum += s[i]; + ApplySwizzleS(s, V_Quad); + + // T prefix generates constants, but abs can change the constant. + u32 tprefixRemove = VFPU_ANY_SWIZZLE(); + u32 tprefixAdd = VFPU_MAKE_CONSTANTS(VFPUConst::ONE, VFPUConst::ONE, VFPUConst::ONE, VFPUConst::ONE); + ApplyPrefixST(t, VFPURewritePrefix(VFPU_CTRL_TPREFIX, tprefixRemove, tprefixAdd), V_Quad); + + d = 0.0f; + for (int i = 0; i < 4; i++) { + d += s[i] * t[i]; } - d = sum; - ApplyPrefixD(&d,V_Single); - V(vd) = d; + ApplyPrefixD(&d, V_Single); + WriteVector(&d, V_Single, vd); PC += 4; EatPrefixes(); } - void Int_Vavg(MIPSOpcode op) - { - float s[4]; + void Int_Vavg(MIPSOpcode op) { + float s[4]{}, t[4]{}; float d; int vd = _VD; int vs = _VS; VectorSize sz = GetVecSize(op); ReadVector(s, sz, vs); - ApplySwizzleS(s, sz); - float sum = 0.0f; - int n = GetNumVectorElements(sz); - for (int i = 0; i < n; i++) - { - sum += s[i]; + ApplySwizzleS(s, V_Quad); + + // T prefix generates constants, but supports negate. + u32 tprefixRemove = VFPU_ANY_SWIZZLE() | VFPU_ABS(1, 1, 1, 1); + u32 tprefixAdd; + if (sz == V_Single) + tprefixAdd = VFPU_MAKE_CONSTANTS(VFPUConst::ZERO, VFPUConst::ZERO, VFPUConst::ZERO, VFPUConst::ZERO); + else if (sz == V_Pair) + tprefixAdd = VFPU_MAKE_CONSTANTS(VFPUConst::HALF, VFPUConst::HALF, VFPUConst::HALF, VFPUConst::HALF); + else if (sz == V_Triple) + tprefixAdd = VFPU_MAKE_CONSTANTS(VFPUConst::THIRD, VFPUConst::THIRD, VFPUConst::THIRD, VFPUConst::THIRD); + else if (sz == V_Quad) + tprefixAdd = VFPU_MAKE_CONSTANTS(VFPUConst::FOURTH, VFPUConst::FOURTH, VFPUConst::FOURTH, VFPUConst::FOURTH); + else + tprefixAdd = 0; + ApplyPrefixST(t, VFPURewritePrefix(VFPU_CTRL_TPREFIX, tprefixRemove, tprefixAdd), V_Quad); + + d = 0.0f; + for (int i = 0; i < 4; i++) { + d += s[i] * t[i]; } - d = sum / n; ApplyPrefixD(&d, V_Single); - V(vd) = d; + WriteVector(&d, V_Single, vd); PC += 4; EatPrefixes(); }