mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-05-08 03:28:31 +03:00
Common: Move floating-point utility functions to FloatUtils.h/.cpp
Keeps all of the floating-point utility functions in their own file to keep them all together. This also provides a place for other general-purpose floating-point functions to be added in the future, which will be necessary when improving the flag-setting within the interpreter.
This commit is contained in:
parent
756ef54ab6
commit
86018b503b
17 changed files with 474 additions and 434 deletions
|
@ -10,7 +10,7 @@
|
|||
|
||||
#include "Common/CPUDetect.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/MathUtil.h"
|
||||
#include "Common/FloatUtils.h"
|
||||
#include "Core/PowerPC/Gekko.h"
|
||||
#include "Core/PowerPC/PowerPC.h"
|
||||
|
||||
|
@ -56,7 +56,7 @@ inline double ForceSingle(double value)
|
|||
float x = (float)value;
|
||||
if (!cpu_info.bFlushToZero && FPSCR.NI)
|
||||
{
|
||||
x = MathUtil::FlushToZero(x);
|
||||
x = Common::FlushToZero(x);
|
||||
}
|
||||
// ...and back to double:
|
||||
return x;
|
||||
|
@ -66,7 +66,7 @@ inline double ForceDouble(double d)
|
|||
{
|
||||
if (!cpu_info.bFlushToZero && FPSCR.NI)
|
||||
{
|
||||
d = MathUtil::FlushToZero(d);
|
||||
d = Common::FlushToZero(d);
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ inline double MakeQuiet(double d)
|
|||
u64 integral;
|
||||
std::memcpy(&integral, &d, sizeof(u64));
|
||||
|
||||
integral |= MathUtil::DOUBLE_QBIT;
|
||||
integral |= Common::DOUBLE_QBIT;
|
||||
|
||||
double result;
|
||||
std::memcpy(&result, &integral, sizeof(double));
|
||||
|
@ -227,13 +227,13 @@ inline double NI_msub(double a, double c, double b)
|
|||
inline u32 ConvertToSingle(u64 x)
|
||||
{
|
||||
u32 exp = (x >> 52) & 0x7ff;
|
||||
if (exp > 896 || (x & ~MathUtil::DOUBLE_SIGN) == 0)
|
||||
if (exp > 896 || (x & ~Common::DOUBLE_SIGN) == 0)
|
||||
{
|
||||
return ((x >> 32) & 0xc0000000) | ((x >> 29) & 0x3fffffff);
|
||||
}
|
||||
else if (exp >= 874)
|
||||
{
|
||||
u32 t = (u32)(0x80000000 | ((x & MathUtil::DOUBLE_FRAC) >> 21));
|
||||
u32 t = (u32)(0x80000000 | ((x & Common::DOUBLE_FRAC) >> 21));
|
||||
t = t >> (905 - exp);
|
||||
t |= (x >> 32) & 0x80000000;
|
||||
return t;
|
||||
|
@ -250,7 +250,7 @@ inline u32 ConvertToSingle(u64 x)
|
|||
inline u32 ConvertToSingleFTZ(u64 x)
|
||||
{
|
||||
u32 exp = (x >> 52) & 0x7ff;
|
||||
if (exp > 896 || (x & ~MathUtil::DOUBLE_SIGN) == 0)
|
||||
if (exp > 896 || (x & ~Common::DOUBLE_SIGN) == 0)
|
||||
{
|
||||
return ((x >> 32) & 0xc0000000) | ((x >> 29) & 0x3fffffff);
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include <limits>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/MathUtil.h"
|
||||
#include "Common/FloatUtils.h"
|
||||
#include "Core/PowerPC/Interpreter/Interpreter.h"
|
||||
#include "Core/PowerPC/Interpreter/Interpreter_FPUtils.h"
|
||||
#include "Core/PowerPC/PowerPC.h"
|
||||
|
@ -25,7 +25,7 @@ void Interpreter::Helper_FloatCompareOrdered(UGeckoInstruction inst, double fa,
|
|||
if (std::isnan(fa) || std::isnan(fb))
|
||||
{
|
||||
compare_result = FPCC::FU;
|
||||
if (MathUtil::IsSNAN(fa) || MathUtil::IsSNAN(fb))
|
||||
if (Common::IsSNAN(fa) || Common::IsSNAN(fb))
|
||||
{
|
||||
SetFPException(FPSCR_VXSNAN);
|
||||
if (FPSCR.VE == 0)
|
||||
|
@ -67,7 +67,7 @@ void Interpreter::Helper_FloatCompareUnordered(UGeckoInstruction inst, double fa
|
|||
{
|
||||
compare_result = FPCC::FU;
|
||||
|
||||
if (MathUtil::IsSNAN(fa) || MathUtil::IsSNAN(fb))
|
||||
if (Common::IsSNAN(fa) || Common::IsSNAN(fb))
|
||||
{
|
||||
SetFPException(FPSCR_VXSNAN);
|
||||
}
|
||||
|
@ -373,7 +373,7 @@ void Interpreter::fdivsx(UGeckoInstruction inst)
|
|||
void Interpreter::fresx(UGeckoInstruction inst)
|
||||
{
|
||||
double b = rPS0(inst.FB);
|
||||
rPS0(inst.FD) = rPS1(inst.FD) = MathUtil::ApproximateReciprocal(b);
|
||||
rPS0(inst.FD) = rPS1(inst.FD) = Common::ApproximateReciprocal(b);
|
||||
|
||||
if (b == 0.0)
|
||||
{
|
||||
|
@ -399,7 +399,7 @@ void Interpreter::frsqrtex(UGeckoInstruction inst)
|
|||
SetFPException(FPSCR_ZX);
|
||||
}
|
||||
|
||||
rPS0(inst.FD) = MathUtil::ApproximateReciprocalSquareRoot(b);
|
||||
rPS0(inst.FD) = Common::ApproximateReciprocalSquareRoot(b);
|
||||
PowerPC::UpdateFPRF(rPS0(inst.FD));
|
||||
|
||||
if (inst.Rc)
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include <cmath>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/MathUtil.h"
|
||||
#include "Common/FloatUtils.h"
|
||||
#include "Core/PowerPC/Interpreter/Interpreter.h"
|
||||
#include "Core/PowerPC/Interpreter/Interpreter_FPUtils.h"
|
||||
#include "Core/PowerPC/PowerPC.h"
|
||||
|
@ -123,8 +123,8 @@ void Interpreter::ps_res(UGeckoInstruction inst)
|
|||
SetFPException(FPSCR_ZX);
|
||||
}
|
||||
|
||||
rPS0(inst.FD) = MathUtil::ApproximateReciprocal(a);
|
||||
rPS1(inst.FD) = MathUtil::ApproximateReciprocal(b);
|
||||
rPS0(inst.FD) = Common::ApproximateReciprocal(a);
|
||||
rPS1(inst.FD) = Common::ApproximateReciprocal(b);
|
||||
PowerPC::UpdateFPRF(rPS0(inst.FD));
|
||||
|
||||
if (inst.Rc)
|
||||
|
@ -143,8 +143,8 @@ void Interpreter::ps_rsqrte(UGeckoInstruction inst)
|
|||
SetFPException(FPSCR_VXSQRT);
|
||||
}
|
||||
|
||||
rPS0(inst.FD) = ForceSingle(MathUtil::ApproximateReciprocalSquareRoot(rPS0(inst.FB)));
|
||||
rPS1(inst.FD) = ForceSingle(MathUtil::ApproximateReciprocalSquareRoot(rPS1(inst.FB)));
|
||||
rPS0(inst.FD) = ForceSingle(Common::ApproximateReciprocalSquareRoot(rPS0(inst.FB)));
|
||||
rPS1(inst.FD) = ForceSingle(Common::ApproximateReciprocalSquareRoot(rPS1(inst.FB)));
|
||||
|
||||
PowerPC::UpdateFPRF(rPS0(inst.FD));
|
||||
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
|
||||
#include "Common/Assert.h"
|
||||
#include "Common/CPUDetect.h"
|
||||
#include "Common/FloatUtils.h"
|
||||
#include "Common/Intrinsics.h"
|
||||
#include "Common/MathUtil.h"
|
||||
#include "Core/HW/MMIO.h"
|
||||
#include "Core/HW/Memmap.h"
|
||||
#include "Core/PowerPC/Gekko.h"
|
||||
|
@ -1060,8 +1060,7 @@ void EmuCodeBlock::SetFPRF(Gen::X64Reg xmm)
|
|||
|
||||
// Nice normalized number: sign ? PPC_FPCLASS_NN : PPC_FPCLASS_PN;
|
||||
LEA(32, RSCRATCH,
|
||||
MScaled(RSCRATCH, MathUtil::PPC_FPCLASS_NN - MathUtil::PPC_FPCLASS_PN,
|
||||
MathUtil::PPC_FPCLASS_PN));
|
||||
MScaled(RSCRATCH, Common::PPC_FPCLASS_NN - Common::PPC_FPCLASS_PN, Common::PPC_FPCLASS_PN));
|
||||
continue1 = J();
|
||||
|
||||
SetJumpTarget(maxExponent);
|
||||
|
@ -1069,14 +1068,14 @@ void EmuCodeBlock::SetFPRF(Gen::X64Reg xmm)
|
|||
FixupBranch notNAN = J_CC(CC_Z);
|
||||
|
||||
// Max exponent + mantissa: PPC_FPCLASS_QNAN
|
||||
MOV(32, R(RSCRATCH), Imm32(MathUtil::PPC_FPCLASS_QNAN));
|
||||
MOV(32, R(RSCRATCH), Imm32(Common::PPC_FPCLASS_QNAN));
|
||||
continue2 = J();
|
||||
|
||||
// Max exponent + no mantissa: sign ? PPC_FPCLASS_NINF : PPC_FPCLASS_PINF;
|
||||
SetJumpTarget(notNAN);
|
||||
LEA(32, RSCRATCH,
|
||||
MScaled(RSCRATCH, MathUtil::PPC_FPCLASS_NINF - MathUtil::PPC_FPCLASS_PINF,
|
||||
MathUtil::PPC_FPCLASS_PINF));
|
||||
MScaled(RSCRATCH, Common::PPC_FPCLASS_NINF - Common::PPC_FPCLASS_PINF,
|
||||
Common::PPC_FPCLASS_PINF));
|
||||
continue3 = J();
|
||||
|
||||
SetJumpTarget(zeroExponent);
|
||||
|
@ -1085,14 +1084,13 @@ void EmuCodeBlock::SetFPRF(Gen::X64Reg xmm)
|
|||
|
||||
// No exponent + mantissa: sign ? PPC_FPCLASS_ND : PPC_FPCLASS_PD;
|
||||
LEA(32, RSCRATCH,
|
||||
MScaled(RSCRATCH, MathUtil::PPC_FPCLASS_ND - MathUtil::PPC_FPCLASS_PD,
|
||||
MathUtil::PPC_FPCLASS_PD));
|
||||
MScaled(RSCRATCH, Common::PPC_FPCLASS_ND - Common::PPC_FPCLASS_PD, Common::PPC_FPCLASS_PD));
|
||||
continue4 = J();
|
||||
|
||||
// Zero: sign ? PPC_FPCLASS_NZ : PPC_FPCLASS_PZ;
|
||||
SetJumpTarget(zero);
|
||||
SHL(32, R(RSCRATCH), Imm8(4));
|
||||
ADD(32, R(RSCRATCH), Imm8(MathUtil::PPC_FPCLASS_PZ));
|
||||
ADD(32, R(RSCRATCH), Imm8(Common::PPC_FPCLASS_PZ));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1107,33 +1105,31 @@ void EmuCodeBlock::SetFPRF(Gen::X64Reg xmm)
|
|||
MOVQ_xmm(R(RSCRATCH), xmm);
|
||||
SHR(64, R(RSCRATCH), Imm8(63));
|
||||
LEA(32, RSCRATCH,
|
||||
MScaled(RSCRATCH, MathUtil::PPC_FPCLASS_NN - MathUtil::PPC_FPCLASS_PN,
|
||||
MathUtil::PPC_FPCLASS_PN));
|
||||
MScaled(RSCRATCH, Common::PPC_FPCLASS_NN - Common::PPC_FPCLASS_PN, Common::PPC_FPCLASS_PN));
|
||||
continue1 = J();
|
||||
SetJumpTarget(nan);
|
||||
MOVQ_xmm(R(RSCRATCH), xmm);
|
||||
SHR(64, R(RSCRATCH), Imm8(63));
|
||||
MOV(32, R(RSCRATCH), Imm32(MathUtil::PPC_FPCLASS_QNAN));
|
||||
MOV(32, R(RSCRATCH), Imm32(Common::PPC_FPCLASS_QNAN));
|
||||
continue2 = J();
|
||||
SetJumpTarget(infinity);
|
||||
MOVQ_xmm(R(RSCRATCH), xmm);
|
||||
SHR(64, R(RSCRATCH), Imm8(63));
|
||||
LEA(32, RSCRATCH,
|
||||
MScaled(RSCRATCH, MathUtil::PPC_FPCLASS_NINF - MathUtil::PPC_FPCLASS_PINF,
|
||||
MathUtil::PPC_FPCLASS_PINF));
|
||||
MScaled(RSCRATCH, Common::PPC_FPCLASS_NINF - Common::PPC_FPCLASS_PINF,
|
||||
Common::PPC_FPCLASS_PINF));
|
||||
continue3 = J();
|
||||
SetJumpTarget(zeroExponent);
|
||||
TEST(64, R(RSCRATCH), R(RSCRATCH));
|
||||
FixupBranch zero = J_CC(CC_Z);
|
||||
SHR(64, R(RSCRATCH), Imm8(63));
|
||||
LEA(32, RSCRATCH,
|
||||
MScaled(RSCRATCH, MathUtil::PPC_FPCLASS_ND - MathUtil::PPC_FPCLASS_PD,
|
||||
MathUtil::PPC_FPCLASS_PD));
|
||||
MScaled(RSCRATCH, Common::PPC_FPCLASS_ND - Common::PPC_FPCLASS_PD, Common::PPC_FPCLASS_PD));
|
||||
continue4 = J();
|
||||
SetJumpTarget(zero);
|
||||
SHR(64, R(RSCRATCH), Imm8(63));
|
||||
SHL(32, R(RSCRATCH), Imm8(4));
|
||||
ADD(32, R(RSCRATCH), Imm8(MathUtil::PPC_FPCLASS_PZ));
|
||||
ADD(32, R(RSCRATCH), Imm8(Common::PPC_FPCLASS_PZ));
|
||||
}
|
||||
|
||||
SetJumpTarget(continue1);
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
|
||||
#include "Common/CPUDetect.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/FloatUtils.h"
|
||||
#include "Common/JitRegister.h"
|
||||
#include "Common/MathUtil.h"
|
||||
#include "Common/x64ABI.h"
|
||||
#include "Common/x64Emitter.h"
|
||||
#include "Core/PowerPC/Gekko.h"
|
||||
|
@ -57,15 +57,15 @@ void CommonAsmRoutines::GenFrsqrte()
|
|||
XOR(32, R(RSCRATCH_EXTRA), Imm8(0x10)); // int index = i / 2048 + (odd_exponent ? 16 : 0);
|
||||
|
||||
PUSH(RSCRATCH2);
|
||||
MOV(64, R(RSCRATCH2), ImmPtr(GetConstantFromPool(MathUtil::frsqrte_expected)));
|
||||
static_assert(sizeof(MathUtil::BaseAndDec) == 8, "Unable to use SCALE_8; incorrect size");
|
||||
MOV(64, R(RSCRATCH2), ImmPtr(GetConstantFromPool(Common::frsqrte_expected)));
|
||||
static_assert(sizeof(Common::BaseAndDec) == 8, "Unable to use SCALE_8; incorrect size");
|
||||
|
||||
SHR(64, R(RSCRATCH), Imm8(37));
|
||||
AND(32, R(RSCRATCH), Imm32(0x7FF));
|
||||
IMUL(32, RSCRATCH,
|
||||
MComplex(RSCRATCH2, RSCRATCH_EXTRA, SCALE_8, offsetof(MathUtil::BaseAndDec, m_dec)));
|
||||
MComplex(RSCRATCH2, RSCRATCH_EXTRA, SCALE_8, offsetof(Common::BaseAndDec, m_dec)));
|
||||
MOV(32, R(RSCRATCH_EXTRA),
|
||||
MComplex(RSCRATCH2, RSCRATCH_EXTRA, SCALE_8, offsetof(MathUtil::BaseAndDec, m_base)));
|
||||
MComplex(RSCRATCH2, RSCRATCH_EXTRA, SCALE_8, offsetof(Common::BaseAndDec, m_base)));
|
||||
SUB(32, R(RSCRATCH_EXTRA), R(RSCRATCH));
|
||||
SHL(64, R(RSCRATCH_EXTRA), Imm8(26));
|
||||
|
||||
|
@ -94,7 +94,7 @@ void CommonAsmRoutines::GenFrsqrte()
|
|||
SetJumpTarget(complex2);
|
||||
SetJumpTarget(complex3);
|
||||
ABI_PushRegistersAndAdjustStack(QUANTIZED_REGS_TO_SAVE, 8);
|
||||
ABI_CallFunction(MathUtil::ApproximateReciprocalSquareRoot);
|
||||
ABI_CallFunction(Common::ApproximateReciprocalSquareRoot);
|
||||
ABI_PopRegistersAndAdjustStack(QUANTIZED_REGS_TO_SAVE, 8);
|
||||
RET();
|
||||
|
||||
|
@ -135,16 +135,16 @@ void CommonAsmRoutines::GenFres()
|
|||
AND(32, R(RSCRATCH2), Imm8(0x1F)); // i / 1024
|
||||
|
||||
PUSH(RSCRATCH_EXTRA);
|
||||
MOV(64, R(RSCRATCH_EXTRA), ImmPtr(GetConstantFromPool(MathUtil::fres_expected)));
|
||||
static_assert(sizeof(MathUtil::BaseAndDec) == 8, "Unable to use SCALE_8; incorrect size");
|
||||
MOV(64, R(RSCRATCH_EXTRA), ImmPtr(GetConstantFromPool(Common::fres_expected)));
|
||||
static_assert(sizeof(Common::BaseAndDec) == 8, "Unable to use SCALE_8; incorrect size");
|
||||
|
||||
IMUL(32, RSCRATCH,
|
||||
MComplex(RSCRATCH_EXTRA, RSCRATCH2, SCALE_8, offsetof(MathUtil::BaseAndDec, m_dec)));
|
||||
MComplex(RSCRATCH_EXTRA, RSCRATCH2, SCALE_8, offsetof(Common::BaseAndDec, m_dec)));
|
||||
ADD(32, R(RSCRATCH), Imm8(1));
|
||||
SHR(32, R(RSCRATCH), Imm8(1));
|
||||
|
||||
MOV(32, R(RSCRATCH2),
|
||||
MComplex(RSCRATCH_EXTRA, RSCRATCH2, SCALE_8, offsetof(MathUtil::BaseAndDec, m_base)));
|
||||
MComplex(RSCRATCH_EXTRA, RSCRATCH2, SCALE_8, offsetof(Common::BaseAndDec, m_base)));
|
||||
SUB(32, R(RSCRATCH2), R(RSCRATCH));
|
||||
SHL(64, R(RSCRATCH2), Imm8(29));
|
||||
|
||||
|
@ -165,7 +165,7 @@ void CommonAsmRoutines::GenFres()
|
|||
|
||||
SetJumpTarget(complex);
|
||||
ABI_PushRegistersAndAdjustStack(QUANTIZED_REGS_TO_SAVE, 8);
|
||||
ABI_CallFunction(MathUtil::ApproximateReciprocal);
|
||||
ABI_CallFunction(Common::ApproximateReciprocal);
|
||||
ABI_PopRegistersAndAdjustStack(QUANTIZED_REGS_TO_SAVE, 8);
|
||||
RET();
|
||||
|
||||
|
|
|
@ -11,8 +11,8 @@
|
|||
#include "Common/ChunkFile.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/FPURoundMode.h"
|
||||
#include "Common/FloatUtils.h"
|
||||
#include "Common/Logging/Log.h"
|
||||
#include "Common/MathUtil.h"
|
||||
|
||||
#include "Core/ConfigManager.h"
|
||||
#include "Core/CoreTiming.h"
|
||||
|
@ -563,7 +563,7 @@ void CheckBreakPoints()
|
|||
|
||||
void UpdateFPRF(double dvalue)
|
||||
{
|
||||
FPSCR.FPRF = MathUtil::ClassifyDouble(dvalue);
|
||||
FPSCR.FPRF = Common::ClassifyDouble(dvalue);
|
||||
}
|
||||
|
||||
} // namespace PowerPC
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue