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