Interpreter_FPUtils: Don't use a union to type-pun between integral and FP types

The previous code invokes undefined behavior. memcpy will optimize away
to the relevant loads and stores while maintaining well-defined
behavior.
This commit is contained in:
Lioncash 2018-04-11 18:51:59 -04:00
parent bbd1bb8eaa
commit 7a3158a693
1 changed files with 19 additions and 6 deletions

View File

@ -5,6 +5,7 @@
#pragma once #pragma once
#include <cmath> #include <cmath>
#include <cstring>
#include <limits> #include <limits>
#include "Common/CPUDetect.h" #include "Common/CPUDetect.h"
@ -71,16 +72,28 @@ inline double ForceDouble(double d)
inline double Force25Bit(double d) inline double Force25Bit(double d)
{ {
MathUtil::IntDouble x(d); u64 integral;
x.i = (x.i & 0xFFFFFFFFF8000000ULL) + (x.i & 0x8000000); std::memcpy(&integral, &d, sizeof(u64));
return x.d;
integral = (integral & 0xFFFFFFFFF8000000ULL) + (integral & 0x8000000);
double result;
std::memcpy(&result, &integral, sizeof(double));
return result;
} }
inline double MakeQuiet(double d) inline double MakeQuiet(double d)
{ {
MathUtil::IntDouble x(d); u64 integral;
x.i |= MathUtil::DOUBLE_QBIT; std::memcpy(&integral, &d, sizeof(u64));
return x.d;
integral |= MathUtil::DOUBLE_QBIT;
double result;
std::memcpy(&result, &integral, sizeof(double));
return result;
} }
// these functions allow globally modify operations behaviour // these functions allow globally modify operations behaviour