From a001b8b6f07d005e9222d7b1351969add9c47006 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Mon, 18 Feb 2013 22:06:49 -0800 Subject: [PATCH] Tweak and note vsat0/vsat1 NaN handling. --- Core/MIPS/MIPSIntVFPU.cpp | 10 +++++----- Core/MIPS/x86/CompVFPU.cpp | 2 ++ 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Core/MIPS/MIPSIntVFPU.cpp b/Core/MIPS/MIPSIntVFPU.cpp index a64be2caf7..97f43c75c5 100644 --- a/Core/MIPS/MIPSIntVFPU.cpp +++ b/Core/MIPS/MIPSIntVFPU.cpp @@ -85,6 +85,9 @@ #ifdef __APPLE__ using std::isnan; #endif +#ifdef _MSC_VER +#define isnan _isnan +#endif void ApplyPrefixST(float *v, u32 data, VectorSize size) { @@ -486,7 +489,8 @@ namespace MIPSInt case 0: d[i] = s[i]; break; //vmov case 1: d[i] = fabsf(s[i]); break; //vabs case 2: d[i] = -s[i]; break; //vneg - case 4: if (s[i] < 0) d[i] = 0; else {if(s[i] > 1.0f) d[i] = 1.0f; else d[i] = s[i];} break; // vsat0 + // vsat0 changes -0.0 to +0.0. + case 4: if (s[i] <= 0) d[i] = 0; else {if(s[i] > 1.0f) d[i] = 1.0f; else d[i] = s[i];} break; // vsat0 case 5: if (s[i] < -1.0f) d[i] = -1.0f; else {if(s[i] > 1.0f) d[i] = 1.0f; else d[i] = s[i];} break; // vsat1 case 16: d[i] = 1.0f / s[i]; break; //vrcp case 17: d[i] = 1.0f / sqrtf(s[i]); break; //vrsq @@ -1452,10 +1456,6 @@ namespace MIPSInt VC_NS }; -#ifdef _MSC_VER -#define isnan _isnan -#endif - void Int_Vcmp(u32 op) { int vs = _VS; diff --git a/Core/MIPS/x86/CompVFPU.cpp b/Core/MIPS/x86/CompVFPU.cpp index 13ca0a02ee..8e7ccce3d3 100644 --- a/Core/MIPS/x86/CompVFPU.cpp +++ b/Core/MIPS/x86/CompVFPU.cpp @@ -520,12 +520,14 @@ void Jit::Comp_VV2Op(u32 op) { case 4: // if (s[i] < 0) d[i] = 0; else {if(s[i] > 1.0f) d[i] = 1.0f; else d[i] = s[i];} break; // vsat0 if (!fpr.V(sregs[i]).IsSimpleReg(tempxregs[i])) MOVSS(tempxregs[i], fpr.V(sregs[i])); + // TODO: Doesn't handle NaN correctly. MAXSS(tempxregs[i], M((void *)&zero)); MINSS(tempxregs[i], M((void *)&one)); break; case 5: // if (s[i] < -1.0f) d[i] = -1.0f; else {if(s[i] > 1.0f) d[i] = 1.0f; else d[i] = s[i];} break; // vsat1 if (!fpr.V(sregs[i]).IsSimpleReg(tempxregs[i])) MOVSS(tempxregs[i], fpr.V(sregs[i])); + // TODO: Doesn't handle NaN correctly. MAXSS(tempxregs[i], M((void *)&minus_one)); MINSS(tempxregs[i], M((void *)&one)); break;