summaryrefslogtreecommitdiff
path: root/Source/Core/Common/FloatUtils.cpp
diff options
context:
space:
mode:
authorLioncash <mathew1800@gmail.com>2018-05-09 09:51:38 -0400
committerLioncash <mathew1800@gmail.com>2018-05-09 10:25:23 -0400
commitf29e7fea2a776c286fc2ca85d66e015f122fdcd8 (patch)
tree341ac6aa8b7d95d73a120459225420cc0c6e2382 /Source/Core/Common/FloatUtils.cpp
parentfe218ea3f60ccb49b88c8a5bdcc70f75455dc761 (diff)
FloatUtils: Remove union type punning from ClassifyX functions
Type-punning via unions is undefined behavior in C++ Also take the liberty of cleaning these up a little bit by removing unnecessary else usages.
Diffstat (limited to 'Source/Core/Common/FloatUtils.cpp')
-rw-r--r--Source/Core/Common/FloatUtils.cpp102
1 files changed, 46 insertions, 56 deletions
diff --git a/Source/Core/Common/FloatUtils.cpp b/Source/Core/Common/FloatUtils.cpp
index a05d62eeb0..5c51f805c0 100644
--- a/Source/Core/Common/FloatUtils.cpp
+++ b/Source/Core/Common/FloatUtils.cpp
@@ -11,80 +11,70 @@ namespace Common
{
u32 ClassifyDouble(double dvalue)
{
- // TODO: Optimize the below to be as fast as possible.
- IntDouble value(dvalue);
- u64 sign = value.i & DOUBLE_SIGN;
- u64 exp = value.i & DOUBLE_EXP;
+ u64 ivalue;
+ std::memcpy(&ivalue, &dvalue, sizeof(ivalue));
+
+ const u64 sign = ivalue & DOUBLE_SIGN;
+ const u64 exp = ivalue & DOUBLE_EXP;
+
if (exp > DOUBLE_ZERO && exp < DOUBLE_EXP)
{
// Nice normalized number.
return sign ? PPC_FPCLASS_NN : PPC_FPCLASS_PN;
}
- else
+
+ const u64 mantissa = ivalue & DOUBLE_FRAC;
+ if (mantissa)
{
- u64 mantissa = value.i & DOUBLE_FRAC;
- if (mantissa)
- {
- if (exp)
- {
- return PPC_FPCLASS_QNAN;
- }
- else
- {
- // Denormalized number.
- return sign ? PPC_FPCLASS_ND : PPC_FPCLASS_PD;
- }
- }
- else if (exp)
- {
- // Infinite
- return sign ? PPC_FPCLASS_NINF : PPC_FPCLASS_PINF;
- }
- else
- {
- // Zero
- return sign ? PPC_FPCLASS_NZ : PPC_FPCLASS_PZ;
- }
+ if (exp)
+ return PPC_FPCLASS_QNAN;
+
+ // Denormalized number.
+ return sign ? PPC_FPCLASS_ND : PPC_FPCLASS_PD;
}
+
+ if (exp)
+ {
+ // Infinite
+ return sign ? PPC_FPCLASS_NINF : PPC_FPCLASS_PINF;
+ }
+
+ // Zero
+ return sign ? PPC_FPCLASS_NZ : PPC_FPCLASS_PZ;
}
u32 ClassifyFloat(float fvalue)
{
- // TODO: Optimize the below to be as fast as possible.
- IntFloat value(fvalue);
- u32 sign = value.i & FLOAT_SIGN;
- u32 exp = value.i & FLOAT_EXP;
+ u32 ivalue;
+ std::memcpy(&ivalue, &fvalue, sizeof(ivalue));
+
+ const u32 sign = ivalue & FLOAT_SIGN;
+ const u32 exp = ivalue & FLOAT_EXP;
+
if (exp > FLOAT_ZERO && exp < FLOAT_EXP)
{
// Nice normalized number.
return sign ? PPC_FPCLASS_NN : PPC_FPCLASS_PN;
}
- else
+
+ const u32 mantissa = ivalue & FLOAT_FRAC;
+ if (mantissa)
{
- u32 mantissa = value.i & FLOAT_FRAC;
- if (mantissa)
- {
- if (exp)
- {
- return PPC_FPCLASS_QNAN; // Quiet NAN
- }
- else
- {
- // Denormalized number.
- return sign ? PPC_FPCLASS_ND : PPC_FPCLASS_PD;
- }
- }
- else if (exp)
- {
- // Infinite
- return sign ? PPC_FPCLASS_NINF : PPC_FPCLASS_PINF;
- }
- else
- {
- // Zero
- return sign ? PPC_FPCLASS_NZ : PPC_FPCLASS_PZ;
- }
+ if (exp)
+ return PPC_FPCLASS_QNAN; // Quiet NAN
+
+ // Denormalized number.
+ return sign ? PPC_FPCLASS_ND : PPC_FPCLASS_PD;
}
+
+ if (exp)
+ {
+ // Infinite
+ return sign ? PPC_FPCLASS_NINF : PPC_FPCLASS_PINF;
+ }
+
+ // Zero
+ return sign ? PPC_FPCLASS_NZ : PPC_FPCLASS_PZ;
}
const std::array<BaseAndDec, 32> frsqrte_expected = {{