mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-11-12 00:59:41 +01:00
x86jit: Handle -0.0 in vavg/vfad.
Should result in a positive result.
This commit is contained in:
1 parent
d0b6a3a339
commit
8a089ee583
1 file changed
+15
-8
@@ -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]));
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user