diff --git a/Core/MIPS/ARM/ArmCompVFPU.cpp b/Core/MIPS/ARM/ArmCompVFPU.cpp index 850b5ebf8ffe..84e84027651d 100644 --- a/Core/MIPS/ARM/ArmCompVFPU.cpp +++ b/Core/MIPS/ARM/ArmCompVFPU.cpp @@ -1832,24 +1832,18 @@ namespace MIPSComp fpr.ReleaseSpillLocksAndDiscardTemps(); } -#ifndef M_PI_2 -#define M_PI_2 1.57079632679489661923 -#endif // sincosf is unavailable in the Android NDK: // https://code.google.com/p/android/issues/detail?id=38423 double SinCos(float angle) { union { struct { float sin; float cos; }; double out; } sincos; - angle *= (float)M_PI_2; - sincos.sin = sinf(angle); - sincos.cos = cosf(angle); + vfpu_sincos(angle, sincos.sin, sincos.cos); return sincos.out; } double SinCosNegSin(float angle) { union { struct { float sin; float cos; }; double out; } sincos; - angle *= (float)M_PI_2; - sincos.sin = -sinf(angle); - sincos.cos = cosf(angle); + vfpu_sincos(angle, sincos.sin, sincos.cos); + sincos.sin = -sincos.sin; return sincos.out; } diff --git a/Core/MIPS/MIPS.cpp b/Core/MIPS/MIPS.cpp index 5a60c8879ec2..e8ffb19b717d 100644 --- a/Core/MIPS/MIPS.cpp +++ b/Core/MIPS/MIPS.cpp @@ -59,7 +59,10 @@ u8 fromvoffset[128]; #define M_LN10 2.30258509299404568402f #undef M_PI #define M_PI 3.14159265358979323846f + +#ifndef M_PI_2 #define M_PI_2 1.57079632679489661923f +#endif #define M_PI_4 0.785398163397448309616f #define M_1_PI 0.318309886183790671538f #define M_2_PI 0.636619772367581343076f diff --git a/Core/MIPS/MIPSIntVFPU.cpp b/Core/MIPS/MIPSIntVFPU.cpp index a8828144d9a7..5c503fe649b8 100644 --- a/Core/MIPS/MIPSIntVFPU.cpp +++ b/Core/MIPS/MIPSIntVFPU.cpp @@ -59,7 +59,9 @@ #define M_LN10 2.30258509299404568402f #undef M_PI #define M_PI 3.14159265358979323846f +#ifndef M_PI_2 #define M_PI_2 1.57079632679489661923f +#endif #define M_PI_4 0.785398163397448309616f #define M_1_PI 0.318309886183790671538f #define M_2_PI 0.636619772367581343076f @@ -517,14 +519,15 @@ namespace MIPSInt 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 - case 18: d[i] = sinf((float)M_PI_2 * s[i]); break; //vsin - case 19: d[i] = cosf((float)M_PI_2 * s[i]); break; //vcos + + case 18: { d[i] = vfpu_sin(s[i]); } break; //vsin + case 19: { d[i] = vfpu_cos(s[i]); } break; //vcos case 20: d[i] = powf(2.0f, s[i]); break; //vexp2 case 21: d[i] = logf(s[i])/log(2.0f); break; //vlog2 case 22: d[i] = fabsf(sqrtf(s[i])); break; //vsqrt case 23: d[i] = asinf(s[i]) / M_PI_2; break; //vasin case 24: d[i] = -1.0f / s[i]; break; // vnrcp - case 26: d[i] = -sinf((float)M_PI_2 * s[i]); break; // vnsin + case 26: { d[i] = -vfpu_sin(s[i]); } break; // vnsin case 28: d[i] = 1.0f / powf(2.0, s[i]); break; // vrexp2 default: _dbg_assert_msg_(CPU,0,"Trying to interpret VV2Op instruction that can't be interpreted"); @@ -1285,21 +1288,18 @@ namespace MIPSInt } // Generates one line of a rotation matrix around one of the three axes - void Int_Vrot(MIPSOpcode op) - { + void Int_Vrot(MIPSOpcode op) { int vd = _VD; int vs = _VS; int imm = (op >> 16) & 0x1f; VectorSize sz = GetVecSize(op); - float angle = V(vs) * M_PI_2; bool negSin = (imm & 0x10) ? true : false; - float sine = sinf(angle); - float cosine = cosf(angle); + float sine, cosine; + vfpu_sincos(V(vs), sine, cosine); if (negSin) sine = -sine; float d[4] = {0}; - if (((imm >> 2) & 3) == (imm & 3)) - { + if (((imm >> 2) & 3) == (imm & 3)) { for (int i = 0; i < 4; i++) d[i] = sine; } @@ -1845,7 +1845,7 @@ namespace MIPSInt ERROR_LOG_REPORT(CPU, "vsbn not implemented for size %d", GetNumVectorElements(sz)); } for (int i = 0; i < GetNumVectorElements(sz); ++i) { - // Simply replace the expontent bits. + // Simply replace the exponent bits. u32 prev = s.u[i] & 0x7F800000; if (prev != 0 && prev != 0x7F800000) { d.u[i] = (s.u[i] & ~0x7F800000) | (exp << 23); diff --git a/Core/MIPS/MIPSVFPUUtils.h b/Core/MIPS/MIPSVFPUUtils.h index 54b3acb5f39a..0632d4bed4e5 100644 --- a/Core/MIPS/MIPSVFPUUtils.h +++ b/Core/MIPS/MIPSVFPUUtils.h @@ -17,17 +17,39 @@ #pragma once - +#include #define _VD (op & 0x7F) #define _VS ((op>>8) & 0x7F) #define _VT ((op>>16) & 0x7F) -inline int Xpose(int v) -{ +inline int Xpose(int v) { return v^0x20; } +#ifndef M_PI_2 +#define M_PI_2 1.57079632679489661923 +#endif + +inline float vfpu_sin(float angle) { + angle -= floorf(angle * 4.0f) * 0.25f; + angle *= (float)M_PI_2; + return sinf(angle); +} + +inline float vfpu_cos(float angle) { + angle -= floorf(angle * 4.0f) * 0.25f; + angle *= (float)M_PI_2; + return cosf(angle); +} + +inline void vfpu_sincos(float angle, float &sine, float &cosine) { + angle -= floorf(angle * 4.0f) * 0.25f; + angle *= (float)M_PI_2; + sine = sinf(angle); + cosine = cosf(angle); +} + #define VFPU_FLOAT16_EXP_MAX 0x1f #define VFPU_SH_FLOAT16_SIGN 15 #define VFPU_MASK_FLOAT16_SIGN 0x1 diff --git a/Core/MIPS/x86/CompVFPU.cpp b/Core/MIPS/x86/CompVFPU.cpp index 0a14e561b526..823c22f6ce70 100644 --- a/Core/MIPS/x86/CompVFPU.cpp +++ b/Core/MIPS/x86/CompVFPU.cpp @@ -2125,15 +2125,12 @@ typedef u32float SinCosArg; #endif void SinCos(SinCosArg angle) { - angle *= (float)1.57079632679489661923; // pi / 2 - sincostemp[0] = sinf(angle); - sincostemp[1] = cosf(angle); + vfpu_sincos(angle, sincostemp[0], sincostemp[1]); } void SinCosNegSin(SinCosArg angle) { - angle *= (float)1.57079632679489661923; // pi / 2 - sincostemp[0] = -sinf(angle); - sincostemp[1] = cosf(angle); + vfpu_sincos(angle, sincostemp[0], sincostemp[1]); + sincostemp[0] = -sincostemp[0]; } // Very heavily used by FF:CC