From 86585e955104ee6a2edfa9cf4511db1cdba9014c Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 24 Apr 2021 15:48:17 -0700 Subject: [PATCH 1/7] unittest: Fix jit harness init. --- Core/MIPS/x86/Jit.cpp | 2 +- unittest/JitHarness.cpp | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Core/MIPS/x86/Jit.cpp b/Core/MIPS/x86/Jit.cpp index 2409af9e8eaa..44e95ca2e58a 100644 --- a/Core/MIPS/x86/Jit.cpp +++ b/Core/MIPS/x86/Jit.cpp @@ -458,7 +458,7 @@ bool Jit::DescribeCodePtr(const u8 *ptr, std::string &name) { name = "UnknownOrDeletedBlock"; } else if (jitAddr != (u32)-1) { char temp[1024]; - const std::string label = g_symbolMap->GetDescription(jitAddr); + const std::string label = g_symbolMap ? g_symbolMap->GetDescription(jitAddr) : ""; if (!label.empty()) snprintf(temp, sizeof(temp), "%08x_%s", jitAddr, label.c_str()); else diff --git a/unittest/JitHarness.cpp b/unittest/JitHarness.cpp index 7ff7f589adc7..9745cc50eb60 100644 --- a/unittest/JitHarness.cpp +++ b/unittest/JitHarness.cpp @@ -23,12 +23,14 @@ #include "Common/System/System.h" #include "Common/TimeUtil.h" #include "Core/ConfigValues.h" +#include "Core/Debugger/SymbolMap.h" #include "Core/MIPS/JitCommon/JitCommon.h" #include "Core/MIPS/JitCommon/JitBlockCache.h" #include "Core/MIPS/MIPSCodeUtils.h" #include "Core/MIPS/MIPSDebugInterface.h" #include "Core/MIPS/MIPSAsm.h" #include "Core/MIPS/MIPSTables.h" +#include "Core/MIPS/MIPSVFPUUtils.h" #include "Core/MemMap.h" #include "Core/Core.h" #include "Core/CoreTiming.h" @@ -82,6 +84,7 @@ static void SetupJitHarness() { // This is pretty much the bare minimum required to setup jit. coreState = CORE_POWERUP; currentMIPS = &mipsr4k; + g_symbolMap = new SymbolMap(); Memory::g_MemorySize = Memory::RAM_NORMAL_SIZE; PSP_CoreParameter().cpuCore = CPUCore::INTERPRETER; PSP_CoreParameter().unthrottle = true; @@ -89,6 +92,7 @@ static void SetupJitHarness() { Memory::Init(); mipsr4k.Reset(); CoreTiming::Init(); + InitVFPUSinCos(true); } static void DestroyJitHarness() { @@ -99,6 +103,7 @@ static void DestroyJitHarness() { Memory::Shutdown(); coreState = CORE_POWERDOWN; currentMIPS = nullptr; + delete g_symbolMap; } bool TestJit() { From e9076c90bb080514bafba3aaef9ec6a3a0598bdb Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 24 Apr 2021 15:49:22 -0700 Subject: [PATCH 2/7] Core: Cleanup VFPU float bit handling. Just to use a common union. --- Core/MIPS/MIPSVFPUUtils.cpp | 82 ++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 46 deletions(-) diff --git a/Core/MIPS/MIPSVFPUUtils.cpp b/Core/MIPS/MIPSVFPUUtils.cpp index e3d0e5ce14fd..e8f932389fe1 100644 --- a/Core/MIPS/MIPSVFPUUtils.cpp +++ b/Core/MIPS/MIPSVFPUUtils.cpp @@ -29,6 +29,11 @@ #define V(i) (currentMIPS->v[voffset[i]]) #define VI(i) (currentMIPS->vi[voffset[i]]) +union float2int { + uint32_t i; + float f; +}; + void GetVectorRegs(u8 regs[4], VectorSize N, int vectorReg) { int mtx = (vectorReg >> 2) & 7; int col = vectorReg & 3; @@ -610,10 +615,7 @@ bool GetVFPUCtrlMask(int reg, u32 *mask) { float Float16ToFloat32(unsigned short l) { - union float2int { - unsigned int i; - float f; - } float2int; + float2int f2i; unsigned short float16 = l; unsigned int sign = (float16 >> VFPU_SH_FLOAT16_SIGN) & VFPU_MASK_FLOAT16_SIGN; @@ -623,10 +625,10 @@ float Float16ToFloat32(unsigned short l) float f; if (exponent == VFPU_FLOAT16_EXP_MAX) { - float2int.i = sign << 31; - float2int.i |= 255 << 23; - float2int.i |= fraction; - f = float2int.f; + f2i.i = sign << 31; + f2i.i |= 255 << 23; + f2i.i |= fraction; + f = f2i.f; } else if (exponent == 0 && fraction == 0) { @@ -647,10 +649,10 @@ float Float16ToFloat32(unsigned short l) } /* Convert to 32-bit single-precision IEEE754. */ - float2int.i = sign << 31; - float2int.i |= (exponent + 112) << 23; - float2int.i |= fraction << 13; - f=float2int.f; + f2i.i = sign << 31; + f2i.i |= (exponent + 112) << 23; + f2i.i |= fraction << 13; + f=f2i.f; } return f; } @@ -674,10 +676,6 @@ static int32_t get_sign(uint32_t x) { float vfpu_dot(float a[4], float b[4]) { static const int EXTRA_BITS = 2; - union float2int { - uint32_t i; - float f; - }; float2int result; float2int src[2]; @@ -791,31 +789,27 @@ float vfpu_dot(float a[4], float b[4]) { // TODO: This is still not completely accurate compared to the PSP's vsqrt. float vfpu_sqrt(float a) { - union float2int { - uint32_t u; - float f; - }; float2int val; val.f = a; - if ((val.u & 0xff800000) == 0x7f800000) { - if ((val.u & 0x007fffff) != 0) { - val.u = 0x7f800001; + if ((val.i & 0xff800000) == 0x7f800000) { + if ((val.i & 0x007fffff) != 0) { + val.i = 0x7f800001; } return val.f; } - if ((val.u & 0x7f800000) == 0) { + if ((val.i & 0x7f800000) == 0) { // Kill any sign. - val.u = 0; + val.i = 0; return val.f; } - if (val.u & 0x80000000) { - val.u = 0x7f800001; + if (val.i & 0x80000000) { + val.i = 0x7f800001; return val.f; } - int k = get_exp(val.u); - uint32_t sp = get_mant(val.u); + int k = get_exp(val.i); + uint32_t sp = get_mant(val.i); int less_bits = k & 1; k >>= 1; @@ -826,9 +820,9 @@ float vfpu_sqrt(float a) { z = (z >> 1) + (uint32_t)(halfsp / z); } - val.u = ((k + 127) << 23) | ((z << less_bits) & 0x007FFFFF); + val.i = ((k + 127) << 23) | ((z << less_bits) & 0x007FFFFF); // The lower two bits never end up set on the PSP, it seems like. - val.u &= 0xFFFFFFFC; + val.i &= 0xFFFFFFFC; return val.f; } @@ -842,31 +836,27 @@ static inline uint32_t mant_mul(uint32_t a, uint32_t b) { } float vfpu_rsqrt(float a) { - union float2int { - uint32_t u; - float f; - }; float2int val; val.f = a; - if (val.u == 0x7f800000) { + if (val.i == 0x7f800000) { return 0.0f; } - if ((val.u & 0x7fffffff) > 0x7f800000) { - val.u = (val.u & 0x80000000) | 0x7f800001; + if ((val.i & 0x7fffffff) > 0x7f800000) { + val.i = (val.i & 0x80000000) | 0x7f800001; return val.f; } - if ((val.u & 0x7f800000) == 0) { - val.u = (val.u & 0x80000000) | 0x7f800000; + if ((val.i & 0x7f800000) == 0) { + val.i = (val.i & 0x80000000) | 0x7f800000; return val.f; } - if (val.u & 0x80000000) { - val.u = 0xff800001; + if (val.i & 0x80000000) { + val.i = 0xff800001; return val.f; } - int k = get_exp(val.u); - uint32_t sp = get_mant(val.u); + int k = get_exp(val.i); + uint32_t sp = get_mant(val.i); int less_bits = k & 1; k = -(k >> 1); @@ -889,8 +879,8 @@ float vfpu_rsqrt(float a) { z >>= less_bits; - val.u = ((k + 127) << 23) | (z & 0x007FFFFF); - val.u &= 0xFFFFFFFC; + val.i = ((k + 127) << 23) | (z & 0x007FFFFF); + val.i &= 0xFFFFFFFC; return val.f; } From ad9ad0f70be334b4f0f33983a1d3763d05de5d03 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 24 Apr 2021 15:51:21 -0700 Subject: [PATCH 3/7] Core: Apply custom narrowing before VFPU sin/cos. This makes the results much more accurate to the PSP's results. Could narrow a bit further swapping sin/cos/neg, which might be what the hardware does given vrot. --- Core/MIPS/MIPSVFPUUtils.cpp | 158 +++++++++++++++++++++++++++++++----- 1 file changed, 139 insertions(+), 19 deletions(-) diff --git a/Core/MIPS/MIPSVFPUUtils.cpp b/Core/MIPS/MIPSVFPUUtils.cpp index e8f932389fe1..540cc7803f6a 100644 --- a/Core/MIPS/MIPSVFPUUtils.cpp +++ b/Core/MIPS/MIPSVFPUUtils.cpp @@ -936,26 +936,146 @@ void vfpu_sincos_single(float angle, float &sine, float &cosine) { } } -float vfpu_sin_double(float angle) { - return (float)sin((double)angle * M_PI_2); +float vfpu_sin_mod2(float a) { + float2int val; + val.f = a; + + int32_t k = get_uexp(val.i); + if (k == 255) { + val.i = (val.i & 0xFF800001) | 1; + return val.f; + } + + if (k < 0x68) { + val.i &= 0x80000000; + return val.f; + } + + // Okay, now modulus by 4 to begin with (identical wave every 4.) + int32_t mantissa = get_mant(val.i); + if (k > 0x80) { + const uint8_t over = k & 0x1F; + mantissa = (mantissa << over) & 0x00FFFFFF; + k = 0x80; + } + // This subtracts off the 2. If we do, flip sign to inverse the wave. + if (k == 0x80 && mantissa >= (1 << 23)) { + val.i ^= 0x80000000; + mantissa -= 1 << 23; + } + + int8_t norm_shift = mantissa == 0 ? 32 : (int8_t)clz32_nonzero(mantissa) - 8; + mantissa <<= norm_shift; + k -= norm_shift; + + if (k <= 0 || mantissa == 0) { + val.i &= 0x80000000; + return val.f; + } + + // This is the value with modulus applied. + val.i = (val.i & 0x80000000) | (k << 23) | (mantissa & ~(1 << 23)); + return (float)sin((double)val.f * M_PI_2); } -float vfpu_cos_double(float angle) { - return (float)cos((double)angle * M_PI_2); +float vfpu_cos_mod2(float a) { + float2int val; + val.f = a; + bool negate = false; + + int32_t k = get_uexp(val.i); + if (k == 255) { + // Note: unlike sin, cos always returns +NAN. + val.i = (val.i & 0x7F800001) | 1; + return val.f; + } + + if (k < 0x68) + return 1.0f; + + // Okay, now modulus by 4 to begin with (identical wave every 4.) + int32_t mantissa = get_mant(val.i); + if (k > 0x80) { + const uint8_t over = k & 0x1F; + mantissa = (mantissa << over) & 0x00FFFFFF; + k = 0x80; + } + // This subtracts off the 2. If we do, negate the result value. + if (k == 0x80 && mantissa >= (1 << 23)) { + mantissa -= 1 << 23; + negate = true; + } + + int8_t norm_shift = mantissa == 0 ? 32 : (int8_t)clz32_nonzero(mantissa) - 8; + mantissa <<= norm_shift; + k -= norm_shift; + + if (k <= 0 || mantissa == 0) + return negate ? -1.0f : 1.0f; + + // This is the value with modulus applied. + val.i = (val.i & 0x80000000) | (k << 23) | (mantissa & ~(1 << 23)); + val.f = (float)cos((double)val.f * M_PI_2); + return negate ? -val.f : val.f; } -void vfpu_sincos_double(float angle_f, float &sine, float &cosine) { - double angle = (double)angle_f * M_PI_2; -#if defined(__linux__) - double d_sine; - double d_cosine; - sincos(angle, &d_sine, &d_cosine); - sine = (float)d_sine; - cosine = (float)d_cosine; -#else - sine = (float)sin(angle); - cosine = (float)cos(angle); -#endif +void vfpu_sincos_mod2(float a, float &s, float &c) { + float2int val; + val.f = a; + // For sin, negate the input, for cos negate the output. + bool negate = false; + + int32_t k = get_uexp(val.i); + if (k == 255) { + val.i = (val.i & 0xFF800001) | 1; + s = val.f; + val.i &= 0x7F800001; + c = val.f; + return; + } + + if (k < 0x68) { + val.i &= 0x80000000; + s = val.f; + c = 1.0f; + return; + } + + // Okay, now modulus by 4 to begin with (identical wave every 4.) + int32_t mantissa = get_mant(val.i); + if (k > 0x80) { + const uint8_t over = k & 0x1F; + mantissa = (mantissa << over) & 0x00FFFFFF; + k = 0x80; + } + // This subtracts off the 2. If we do, flip signs. + if (k == 0x80 && mantissa >= (1 << 23)) { + mantissa -= 1 << 23; + negate = true; + } + + int8_t norm_shift = mantissa == 0 ? 32 : (int8_t)clz32_nonzero(mantissa) - 8; + mantissa <<= norm_shift; + k -= norm_shift; + + if (k <= 0 || mantissa == 0) { + val.i &= 0x80000000; + if (negate) + val.i ^= 0x80000000; + s = val.f; + c = 1.0f; + return; + } + + // This is the value with modulus applied. + val.i = (val.i & 0x80000000) | (k << 23) | (mantissa & ~(1 << 23)); + if (negate) { + s = (float)sin((double)-val.f * M_PI_2); + c = -(float)cos((double)val.f * M_PI_2); + } else { + s = (float)sin((double)val.f * M_PI_2); + c = (float)cos((double)val.f * M_PI_2); + } } float (*vfpu_sin)(float); @@ -963,7 +1083,7 @@ float (*vfpu_cos)(float); void (*vfpu_sincos)(float, float&, float&); void InitVFPUSinCos(bool useDoublePrecision) { - vfpu_sin = useDoublePrecision ? vfpu_sin_double : vfpu_sin_single; - vfpu_cos = useDoublePrecision ? vfpu_cos_double : vfpu_cos_single; - vfpu_sincos = useDoublePrecision ? vfpu_sincos_double : vfpu_sincos_single; + vfpu_sin = useDoublePrecision ? vfpu_sin_mod2 : vfpu_sin_single; + vfpu_cos = useDoublePrecision ? vfpu_cos_mod2 : vfpu_cos_single; + vfpu_sincos = useDoublePrecision ? vfpu_sincos_mod2 : vfpu_sincos_single; } From cb8745bca843052f21bb4275efebbe3080c08e4d Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 24 Apr 2021 15:53:25 -0700 Subject: [PATCH 4/7] Core: Switch to double precision VFPU sin/cos. --- Core/System.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/System.cpp b/Core/System.cpp index cf86c440ebb5..19690bb53734 100644 --- a/Core/System.cpp +++ b/Core/System.cpp @@ -284,7 +284,7 @@ bool CPU_Init() { // likely to collide with any commercial ones. coreParameter.compat.Load(g_paramSFO.GetDiscID()); - InitVFPUSinCos(coreParameter.compat.flags().DoublePrecisionSinCos); + InitVFPUSinCos(true); if (allowPlugins) HLEPlugins::Init(); From 8f41c78ed7d602fc8ec9c59220eef8f3bc0f0d68 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 24 Apr 2021 16:01:19 -0700 Subject: [PATCH 5/7] Core: Strip off lower bits of sin/cos results. --- Core/MIPS/MIPSVFPUUtils.cpp | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/Core/MIPS/MIPSVFPUUtils.cpp b/Core/MIPS/MIPSVFPUUtils.cpp index 540cc7803f6a..a7add8093c31 100644 --- a/Core/MIPS/MIPSVFPUUtils.cpp +++ b/Core/MIPS/MIPSVFPUUtils.cpp @@ -975,7 +975,9 @@ float vfpu_sin_mod2(float a) { // This is the value with modulus applied. val.i = (val.i & 0x80000000) | (k << 23) | (mantissa & ~(1 << 23)); - return (float)sin((double)val.f * M_PI_2); + val.f = (float)sin((double)val.f * M_PI_2); + val.i &= 0xFFFFFFFC; + return val.f; } float vfpu_cos_mod2(float a) { @@ -1016,6 +1018,7 @@ float vfpu_cos_mod2(float a) { // This is the value with modulus applied. val.i = (val.i & 0x80000000) | (k << 23) | (mantissa & ~(1 << 23)); val.f = (float)cos((double)val.f * M_PI_2); + val.i &= 0xFFFFFFFC; return negate ? -val.f : val.f; } @@ -1069,13 +1072,29 @@ void vfpu_sincos_mod2(float a, float &s, float &c) { // This is the value with modulus applied. val.i = (val.i & 0x80000000) | (k << 23) | (mantissa & ~(1 << 23)); + float2int i_sine, i_cosine; if (negate) { - s = (float)sin((double)-val.f * M_PI_2); - c = -(float)cos((double)val.f * M_PI_2); + i_sine.f = (float)sin((double)-val.f * M_PI_2); + i_cosine.f = -(float)cos((double)val.f * M_PI_2); } else { - s = (float)sin((double)val.f * M_PI_2); - c = (float)cos((double)val.f * M_PI_2); + double angle = (double)val.f * M_PI_2; +#if defined(__linux__) + double d_sine; + double d_cosine; + sincos(angle, &d_sine, &d_cosine); + i_sine.f = (float)d_sine; + i_cosine.f = (float)d_cosine; +#else + i_sine.f = (float)sin(angle); + i_cosine.f = (float)cos(angle); +#endif } + + i_sine.i &= 0xFFFFFFFC; + i_cosine.i &= 0xFFFFFFFC; + s = i_sine.f; + c = i_cosine.f; + return ; } float (*vfpu_sin)(float); From ad876f06f395f0e4d4b04b5d736f24bc70c7952a Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 24 Apr 2021 16:28:09 -0700 Subject: [PATCH 6/7] Core: Special case 1/-1 for cosine. It still gets these off from zero, so let's just special case. --- Core/MIPS/MIPSVFPUUtils.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Core/MIPS/MIPSVFPUUtils.cpp b/Core/MIPS/MIPSVFPUUtils.cpp index a7add8093c31..be434207c458 100644 --- a/Core/MIPS/MIPSVFPUUtils.cpp +++ b/Core/MIPS/MIPSVFPUUtils.cpp @@ -1017,6 +1017,9 @@ float vfpu_cos_mod2(float a) { // This is the value with modulus applied. val.i = (val.i & 0x80000000) | (k << 23) | (mantissa & ~(1 << 23)); + if (val.f == 1.0f || val.f == -1.0f) { + return negate ? 0.0f : -0.0f; + } val.f = (float)cos((double)val.f * M_PI_2); val.i &= 0xFFFFFFFC; return negate ? -val.f : val.f; @@ -1073,7 +1076,13 @@ void vfpu_sincos_mod2(float a, float &s, float &c) { // This is the value with modulus applied. val.i = (val.i & 0x80000000) | (k << 23) | (mantissa & ~(1 << 23)); float2int i_sine, i_cosine; - if (negate) { + if (val.f == 1.0f) { + i_sine.f = negate ? -1.0f : 1.0f; + i_cosine.f = negate ? 0.0f : -0.0f; + } else if (val.f == -1.0f) { + i_sine.f = negate ? 1.0f : -1.0f; + i_cosine.f = negate ? 0.0f : -0.0f; + } else if (negate) { i_sine.f = (float)sin((double)-val.f * M_PI_2); i_cosine.f = -(float)cos((double)val.f * M_PI_2); } else { From 07cb37c2c1970c4c8185a82d2b60be5a2a6a9804 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 25 Apr 2021 07:09:50 -0700 Subject: [PATCH 7/7] Compat: Remove single/double sincos path. New implementation should work for both cases. --- Core/Compatibility.cpp | 1 - Core/Compatibility.h | 1 - Core/MIPS/MIPSVFPUUtils.cpp | 67 +++---------------------------------- Core/MIPS/MIPSVFPUUtils.h | 8 ++--- Core/System.cpp | 2 +- assets/compat.ini | 6 ---- unittest/JitHarness.cpp | 2 +- unittest/UnitTest.cpp | 2 +- 8 files changed, 12 insertions(+), 77 deletions(-) diff --git a/Core/Compatibility.cpp b/Core/Compatibility.cpp index 45a5bb25bd7c..4522573def7f 100644 --- a/Core/Compatibility.cpp +++ b/Core/Compatibility.cpp @@ -75,7 +75,6 @@ void Compatibility::CheckSettings(IniFile &iniFile, const std::string &gameID) { CheckSetting(iniFile, gameID, "MemstickFixedFree", &flags_.MemstickFixedFree); CheckSetting(iniFile, gameID, "DateLimited", &flags_.DateLimited); CheckSetting(iniFile, gameID, "ReinterpretFramebuffers", &flags_.ReinterpretFramebuffers); - CheckSetting(iniFile, gameID, "DoublePrecisionSinCos", &flags_.DoublePrecisionSinCos); CheckSetting(iniFile, gameID, "ShaderColorBitmask", &flags_.ShaderColorBitmask); CheckSetting(iniFile, gameID, "DisableFirstFrameReadback", &flags_.DisableFirstFrameReadback); CheckSetting(iniFile, gameID, "DisableRangeCulling", &flags_.DisableRangeCulling); diff --git a/Core/Compatibility.h b/Core/Compatibility.h index da0e36c1f639..48eeddc197f5 100644 --- a/Core/Compatibility.h +++ b/Core/Compatibility.h @@ -73,7 +73,6 @@ struct CompatFlags { bool MemstickFixedFree; bool DateLimited; bool ReinterpretFramebuffers; - bool DoublePrecisionSinCos; bool ShaderColorBitmask; bool DisableFirstFrameReadback; bool DisableRangeCulling; diff --git a/Core/MIPS/MIPSVFPUUtils.cpp b/Core/MIPS/MIPSVFPUUtils.cpp index be434207c458..e5d06e8c306d 100644 --- a/Core/MIPS/MIPSVFPUUtils.cpp +++ b/Core/MIPS/MIPSVFPUUtils.cpp @@ -885,58 +885,7 @@ float vfpu_rsqrt(float a) { return val.f; } -float vfpu_sin_single(float angle) { - angle -= floorf(angle * 0.25f) * 4.f; - if (angle == 0.0f || angle == 2.0f) { - return 0.0f; - } else if (angle == 1.0f) { - return 1.0f; - } else if (angle == 3.0f) { - return -1.0f; - } - angle *= (float)M_PI_2; - return sinf(angle); -} - -float vfpu_cos_single(float angle) { - angle -= floorf(angle * 0.25f) * 4.f; - if (angle == 1.0f || angle == 3.0f) { - return 0.0f; - } else if (angle == 0.0f) { - return 1.0f; - } else if (angle == 2.0f) { - return -1.0f; - } - angle *= (float)M_PI_2; - return cosf(angle); -} - -void vfpu_sincos_single(float angle, float &sine, float &cosine) { - angle -= floorf(angle * 0.25f) * 4.f; - if (angle == 0.0f) { - sine = 0.0f; - cosine = 1.0f; - } else if (angle == 1.0f) { - sine = 1.0f; - cosine = 0.0f; - } else if (angle == 2.0f) { - sine = 0.0f; - cosine = -1.0f; - } else if (angle == 3.0f) { - sine = -1.0f; - cosine = 0.0f; - } else { - angle *= (float)M_PI_2; -#if defined(__linux__) - sincosf(angle, &sine, &cosine); -#else - sine = sinf(angle); - cosine = cosf(angle); -#endif - } -} - -float vfpu_sin_mod2(float a) { +float vfpu_sin(float a) { float2int val; val.f = a; @@ -980,7 +929,7 @@ float vfpu_sin_mod2(float a) { return val.f; } -float vfpu_cos_mod2(float a) { +float vfpu_cos(float a) { float2int val; val.f = a; bool negate = false; @@ -1025,7 +974,7 @@ float vfpu_cos_mod2(float a) { return negate ? -val.f : val.f; } -void vfpu_sincos_mod2(float a, float &s, float &c) { +void vfpu_sincos(float a, float &s, float &c) { float2int val; val.f = a; // For sin, negate the input, for cos negate the output. @@ -1106,12 +1055,6 @@ void vfpu_sincos_mod2(float a, float &s, float &c) { return ; } -float (*vfpu_sin)(float); -float (*vfpu_cos)(float); -void (*vfpu_sincos)(float, float&, float&); - -void InitVFPUSinCos(bool useDoublePrecision) { - vfpu_sin = useDoublePrecision ? vfpu_sin_mod2 : vfpu_sin_single; - vfpu_cos = useDoublePrecision ? vfpu_cos_mod2 : vfpu_cos_single; - vfpu_sincos = useDoublePrecision ? vfpu_sincos_mod2 : vfpu_sincos_single; +void InitVFPUSinCos() { + // TODO: Could prepare a CORDIC table here. } diff --git a/Core/MIPS/MIPSVFPUUtils.h b/Core/MIPS/MIPSVFPUUtils.h index b89335a25717..8200e8c87d02 100644 --- a/Core/MIPS/MIPSVFPUUtils.h +++ b/Core/MIPS/MIPSVFPUUtils.h @@ -50,9 +50,9 @@ inline int Xpose(int v) { // // Messing around with the modulo functions? try https://www.desmos.com/calculator. -extern float (*vfpu_sin)(float); -extern float (*vfpu_cos)(float); -extern void (*vfpu_sincos)(float, float&, float&); +extern float vfpu_sin(float); +extern float vfpu_cos(float); +extern void vfpu_sincos(float, float&, float&); inline float vfpu_asin(float angle) { return asinf(angle) / M_PI_2; @@ -215,4 +215,4 @@ int GetVectorOverlap(int reg1, VectorSize size1, int reg2, VectorSize size2); bool GetVFPUCtrlMask(int reg, u32 *mask); float Float16ToFloat32(unsigned short l); -void InitVFPUSinCos(bool useDoublePrecision); +void InitVFPUSinCos(); diff --git a/Core/System.cpp b/Core/System.cpp index 19690bb53734..60a2e03b6bf9 100644 --- a/Core/System.cpp +++ b/Core/System.cpp @@ -284,7 +284,7 @@ bool CPU_Init() { // likely to collide with any commercial ones. coreParameter.compat.Load(g_paramSFO.GetDiscID()); - InitVFPUSinCos(true); + InitVFPUSinCos(); if (allowPlugins) HLEPlugins::Init(); diff --git a/assets/compat.ini b/assets/compat.ini index 91792cf9c069..2b2d0e7f0032 100644 --- a/assets/compat.ini +++ b/assets/compat.ini @@ -989,12 +989,6 @@ ULJM05533 = true NPJH50006 = true ULES01301 = true -[DoublePrecisionSinCos] -# Hitman Reborn Battle Arena 2 (#12900) -ULJS00218 = true -# Hitman Reborn Battle Arena -ULJS00157 = true - [DisableFirstFrameReadback] # Wipeout Pure: Temporary workaround for lens flare flicker. See #13344 UCUS98612 = true diff --git a/unittest/JitHarness.cpp b/unittest/JitHarness.cpp index 9745cc50eb60..6743a5a62e2e 100644 --- a/unittest/JitHarness.cpp +++ b/unittest/JitHarness.cpp @@ -92,7 +92,7 @@ static void SetupJitHarness() { Memory::Init(); mipsr4k.Reset(); CoreTiming::Init(); - InitVFPUSinCos(true); + InitVFPUSinCos(); } static void DestroyJitHarness() { diff --git a/unittest/UnitTest.cpp b/unittest/UnitTest.cpp index f337af9b9698..bc91182cdeff 100644 --- a/unittest/UnitTest.cpp +++ b/unittest/UnitTest.cpp @@ -303,7 +303,7 @@ bool TestParsers() { bool TestVFPUSinCos() { float sine, cosine; - InitVFPUSinCos(false); + InitVFPUSinCos(); EXPECT_FALSE(vfpu_sincos == nullptr); vfpu_sincos(0.0f, sine, cosine); EXPECT_EQ_FLOAT(sine, 0.0f);