From 8a089ee583f4d1d5b435bd2b59dd29a49a47d0bd Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 3 Jan 2015 10:39:26 -0800 Subject: [PATCH 1/3] x86jit: Handle -0.0 in vavg/vfad. Should result in a positive result. --- Core/MIPS/x86/CompVFPU.cpp | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/Core/MIPS/x86/CompVFPU.cpp b/Core/MIPS/x86/CompVFPU.cpp index 9d64ab12f6..5b252cd710 100644 --- a/Core/MIPS/x86/CompVFPU.cpp +++ b/Core/MIPS/x86/CompVFPU.cpp @@ -3123,8 +3123,12 @@ void Jit::Comp_Vhoriz(MIPSOpcode op) { MOVAPS(fpr.VSX(dregs), R(XMM0)); break; case V_Quad: + XORPS(XMM1, R(XMM1)); MOVAPS(XMM0, fpr.VS(sregs)); DPPS(XMM0, M(&oneOneOneOne), 0xF1); + // In every other case, +0.0 is selected by the mask and added. + // But, here we need to manually add it to the result. + ADDPS(XMM0, R(XMM1)); MOVAPS(fpr.VSX(dregs), R(XMM0)); break; default: @@ -3133,15 +3137,17 @@ void Jit::Comp_Vhoriz(MIPSOpcode op) { } else { switch (sz) { case V_Pair: + XORPS(XMM1, R(XMM1)); MOVAPS(XMM0, fpr.VS(sregs)); - MOVAPS(XMM1, R(XMM0)); + ADDPS(XMM1, R(XMM0)); SHUFPS(XMM1, R(XMM1), _MM_SHUFFLE(3, 2, 1, 1)); ADDPS(XMM0, R(XMM1)); MOVAPS(fpr.VSX(dregs), R(XMM0)); break; case V_Triple: + XORPS(XMM1, R(XMM1)); MOVAPS(XMM0, fpr.VS(sregs)); - MOVAPS(XMM1, R(XMM0)); + ADDPS(XMM1, R(XMM0)); SHUFPS(XMM1, R(XMM1), _MM_SHUFFLE(3, 2, 1, 1)); ADDPS(XMM0, R(XMM1)); SHUFPS(XMM1, R(XMM1), _MM_SHUFFLE(3, 2, 1, 2)); @@ -3149,7 +3155,10 @@ void Jit::Comp_Vhoriz(MIPSOpcode op) { MOVAPS(fpr.VSX(dregs), R(XMM0)); break; case V_Quad: + XORPS(XMM1, R(XMM1)); MOVAPS(XMM0, fpr.VS(sregs)); + // This flips the sign of any -0.000. + ADDPS(XMM0, R(XMM1)); MOVHLPS(XMM1, XMM0); ADDPS(XMM0, R(XMM1)); MOVAPS(XMM1, R(XMM0)); @@ -3174,17 +3183,15 @@ void Jit::Comp_Vhoriz(MIPSOpcode op) { fpr.SimpleRegsV(dregs, V_Single, MAP_NOINIT | MAP_DIRTY); X64Reg reg = XMM0; - if (IsOverlapSafeAllowS(dregs[0], 0, n, sregs)) { + if (IsOverlapSafe(dregs[0], 0, n, sregs)) { fpr.MapRegV(dregs[0], dregs[0] == sregs[0] ? MAP_DIRTY : MAP_NOINIT); fpr.SpillLockV(dregs[0]); reg = fpr.VX(dregs[0]); } - // We use a temp reg in case of overlap. - if (!fpr.V(sregs[0]).IsSimpleReg(reg)) { - MOVSS(reg, fpr.V(sregs[0])); - } - for (int i = 1; i < n; ++i) { + // We have to start zt +0.000 in case any values are -0.000. + XORPS(reg, R(reg)); + for (int i = 0; i < n; ++i) { ADDSS(reg, fpr.V(sregs[i])); } From a1864b2c789c5fa16884bcf645b69299cb4b62a0 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 3 Jan 2015 10:39:58 -0800 Subject: [PATCH 2/3] x86jit: Fix vavg scale. Was completely wrong, darn it. --- Core/MIPS/x86/CompVFPU.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Core/MIPS/x86/CompVFPU.cpp b/Core/MIPS/x86/CompVFPU.cpp index 5b252cd710..eaa4bf572b 100644 --- a/Core/MIPS/x86/CompVFPU.cpp +++ b/Core/MIPS/x86/CompVFPU.cpp @@ -3171,7 +3171,7 @@ void Jit::Comp_Vhoriz(MIPSOpcode op) { } } if (((op >> 16) & 31) == 7) { // vavg - MULSS(fpr.VSX(dregs), M(&vavg_table[n])); + MULSS(fpr.VSX(dregs), M(&vavg_table[n - 1])); } ApplyPrefixD(dregs, V_Single); fpr.ReleaseSpillLocks(); @@ -3199,7 +3199,7 @@ void Jit::Comp_Vhoriz(MIPSOpcode op) { case 6: // vfad break; case 7: // vavg - MULSS(reg, M(&vavg_table[n])); + MULSS(reg, M(&vavg_table[n - 1])); break; } From e6a50a13717394b07c2391c33bd3c878519093d8 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 3 Jan 2015 10:40:21 -0800 Subject: [PATCH 3/3] Initialize vfpu regs are NAN, not 0.0. This matches tests, the fpu, and seems logical. --- Core/HLE/sceKernelThread.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/HLE/sceKernelThread.cpp b/Core/HLE/sceKernelThread.cpp index 6a0fd56547..197a4559b6 100644 --- a/Core/HLE/sceKernelThread.cpp +++ b/Core/HLE/sceKernelThread.cpp @@ -1982,7 +1982,7 @@ void ThreadContext::reset() r[0] = 0; for (int i = 0; i<128; i++) { - v[i] = 0.0f; + vi[i] = 0x7f800001; } for (int i = 0; i<15; i++) {