Skip to content
Permalink
Browse files
Merge pull request #6632 from lioncash/fp
Interpreter: Don't use a union to type-pun between integral and FP types
  • Loading branch information
degasus committed Apr 13, 2018
2 parents 0e4bc6e + ab25eb6 commit 71dd2d9
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 17 deletions.
@@ -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
@@ -2,6 +2,7 @@
// Licensed under GPLv2+
// Refer to the license.txt file included.

#include <cstring>
#include <tuple>
#include <type_traits>
#include <utility>
@@ -172,21 +173,28 @@ void Interpreter::Helper_Quantize(u32 addr, u32 instI, u32 instRS, u32 instW)
const EQuantizeType stType = gqr.st_type;
const unsigned int stScale = gqr.st_scale;

double ps0 = rPS0(instRS);
double ps1 = rPS1(instRS);
const double ps0 = rPS0(instRS);
const double ps1 = rPS1(instRS);

switch (stType)
{
case QUANTIZE_FLOAT:
{
u32 convPS0 = ConvertToSingleFTZ(MathUtil::IntDouble(ps0).i);
u64 integral_ps0;
std::memcpy(&integral_ps0, &ps0, sizeof(u64));

const u32 conv_ps0 = ConvertToSingleFTZ(integral_ps0);
if (instW)
{
WriteUnpaired<u32>(convPS0, addr);
WriteUnpaired<u32>(conv_ps0, addr);
}
else
{
u32 convPS1 = ConvertToSingleFTZ(MathUtil::IntDouble(ps1).i);
WritePair<u32>(convPS0, convPS1, addr);
u64 integral_ps1;
std::memcpy(&integral_ps1, &ps1, sizeof(double));

const u32 conv_ps1 = ConvertToSingleFTZ(integral_ps1);
WritePair<u32>(conv_ps0, conv_ps1, addr);
}
break;
}
@@ -249,15 +257,15 @@ void Interpreter::Helper_Dequantize(u32 addr, u32 instI, u32 instRD, u32 instW)
case QUANTIZE_FLOAT:
if (instW)
{
u32 value = ReadUnpaired<u32>(addr);
ps0 = MathUtil::IntFloat(value).f;
const u32 value = ReadUnpaired<u32>(addr);
std::memcpy(&ps0, &value, sizeof(float));
ps1 = 1.0f;
}
else
{
std::pair<u32, u32> value = ReadPair<u32>(addr);
ps0 = MathUtil::IntFloat(value.first).f;
ps1 = MathUtil::IntFloat(value.second).f;
const std::pair<u32, u32> value = ReadPair<u32>(addr);
std::memcpy(&ps0, &value.first, sizeof(float));
std::memcpy(&ps1, &value.second, sizeof(float));
}
break;

0 comments on commit 71dd2d9

Please sign in to comment.