From 85f4f147a1cfeec723c36cd640f0075c63fa9ab2 Mon Sep 17 00:00:00 2001 From: zilmar Date: Tue, 9 May 2023 09:40:10 +0930 Subject: [PATCH] Core: Remove Float_RoundToInteger32 --- .../N64System/Interpreter/InterpreterOps.cpp | 100 +++++++++--------- 1 file changed, 52 insertions(+), 48 deletions(-) diff --git a/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp b/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp index 6fe8f7fe1..04e89fc35 100644 --- a/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp +++ b/Source/Project64-core/N64System/Interpreter/InterpreterOps.cpp @@ -111,13 +111,11 @@ void R4300iOp::COP1_BC() void R4300iOp::COP1_S() { - fesetround(*_RoundingModel); Jump_CoP1_S[m_Opcode.funct](); } void R4300iOp::COP1_D() { - fesetround(*_RoundingModel); Jump_CoP1_D[m_Opcode.funct](); } @@ -2016,48 +2014,6 @@ void R4300iOp::COP1_BCTL() } // COP1: S functions - -__inline void Float_RoundToInteger32(int32_t * Dest, const float * Source, int RoundType) -{ -#pragma warning(push) -#pragma warning(disable : 4244) // warning C4244: disable conversion from 'float' to 'int32_t', possible loss of data - - if (RoundType == FE_TONEAREST) - { - float reminder = *Source - floorf(*Source); - if (reminder == 0.5) - { - // Make any decimal point that is even odd, and any decimal point that is odd stay odd - if (*Source < 0) - { - *Dest = (int)truncf(*Source) % 2 != 0 ? floorf(*Source) : ceilf(*Source); - } - else - { - *Dest = (int)truncf(*Source) % 2 != 0 ? ceilf(*Source) : floorf(*Source); - } - } - else - { - *Dest = roundf(*Source); - } - } - else if (RoundType == FE_TOWARDZERO) - { - *Dest = truncf(*Source); - } - else if (RoundType == FE_UPWARD) - { - *Dest = ceilf(*Source); - } - else if (RoundType == FE_DOWNWARD) - { - *Dest = floorf(*Source); - } - -#pragma warning(pop) -} - __inline void Float_RoundToInteger64(int64_t * Dest, const float * Source, int RoundType) { #pragma warning(push) @@ -2307,7 +2263,19 @@ void R4300iOp::COP1_S_ROUND_W() { return; } - Float_RoundToInteger32(&*(int32_t *)_FPR_S[m_Opcode.fd], &*(float *)_FPR_S[m_Opcode.fs], FE_TONEAREST); + _FPCR[31] &= ~0x0003F000; + fesetround(FE_TONEAREST); + feclearexcept(FE_ALL_EXCEPT); + if (!CheckFPUInput32Conv(*(float *)_FPR_S[m_Opcode.fs])) + { + return; + } + int32_t Result = (int32_t)rint(*(float *)_FPR_S[m_Opcode.fs]); + if (CheckFPUInvalidException()) + { + return; + } + *(uint32_t *)_FPR_S[m_Opcode.fd] = *(uint32_t *)&Result; } void R4300iOp::COP1_S_TRUNC_W() @@ -2316,7 +2284,19 @@ void R4300iOp::COP1_S_TRUNC_W() { return; } - Float_RoundToInteger32(&*(int32_t *)_FPR_S[m_Opcode.fd], &*(float *)_FPR_S[m_Opcode.fs], FE_TOWARDZERO); + _FPCR[31] &= ~0x0003F000; + fesetround(FE_TOWARDZERO); + feclearexcept(FE_ALL_EXCEPT); + if (!CheckFPUInput32Conv(*(float *)_FPR_S[m_Opcode.fs])) + { + return; + } + int32_t Result = (int32_t)rint(*(float *)_FPR_S[m_Opcode.fs]); + if (CheckFPUInvalidException()) + { + return; + } + *(uint32_t *)_FPR_S[m_Opcode.fd] = *(uint32_t *)&Result; } void R4300iOp::COP1_S_CEIL_W() @@ -2325,7 +2305,19 @@ void R4300iOp::COP1_S_CEIL_W() { return; } - Float_RoundToInteger32(&*(int32_t *)_FPR_S[m_Opcode.fd], &*(float *)_FPR_S[m_Opcode.fs], FE_UPWARD); + _FPCR[31] &= ~0x0003F000; + fesetround(FE_UPWARD); + feclearexcept(FE_ALL_EXCEPT); + if (!CheckFPUInput32Conv(*(float *)_FPR_S[m_Opcode.fs])) + { + return; + } + int32_t Result = (int32_t)rint(*(float *)_FPR_S[m_Opcode.fs]); + if (CheckFPUInvalidException()) + { + return; + } + *(uint32_t *)_FPR_S[m_Opcode.fd] = *(uint32_t *)&Result; } void R4300iOp::COP1_S_FLOOR_W() @@ -2334,7 +2326,19 @@ void R4300iOp::COP1_S_FLOOR_W() { return; } - Float_RoundToInteger32(&*(int32_t *)_FPR_S[m_Opcode.fd], &*(float *)_FPR_S[m_Opcode.fs], FE_DOWNWARD); + _FPCR[31] &= ~0x0003F000; + fesetround(FE_DOWNWARD); + feclearexcept(FE_ALL_EXCEPT); + if (!CheckFPUInput32Conv(*(float *)_FPR_S[m_Opcode.fs])) + { + return; + } + int32_t Result = (int32_t)rint(*(float *)_FPR_S[m_Opcode.fs]); + if (CheckFPUInvalidException()) + { + return; + } + *(uint32_t *)_FPR_S[m_Opcode.fd] = *(uint32_t *)&Result; } void R4300iOp::COP1_S_CVT_S()