BitUtils: Add BitCast

libc++ doesn't implement std::bit_cast, so we can provide our own for
the time being.
This commit is contained in:
Lioncash committed 2021-06-17 01:30:07 -04:00
1 parent cba4ca7d01
commit e369626929
2 files changed
+27 -24

No files matched your search

+10 -24
View File
@@ -1,4 +1,6 @@
#pragma once
#include <FEXCore/Utils/BitUtils.h>
#include <FEXCore/Utils/LogManager.h>
#include <cmath>
@@ -159,23 +161,17 @@ struct X80SoftFloat {
operator float() const {
const float32_t Result = extF80_to_f32(*this);
float flt;
std::memcpy(&flt, &Result, sizeof(flt));
return flt;
return FEXCore::BitCast<float>(Result);
}
operator double() const {
const float64_t Result = extF80_to_f64(*this);
double flt;
std::memcpy(&flt, &Result, sizeof(flt));
return flt;
return FEXCore::BitCast<double>(Result);
}
operator BIGFLOAT() const {
const float128_t Result = extF80_to_f128(*this);
BIGFLOAT flt;
std::memcpy(&flt, &Result, sizeof(flt));
return flt;
return FEXCore::BitCast<BIGFLOAT>(Result);
}
operator int16_t() const {
@@ -202,15 +198,11 @@ struct X80SoftFloat {
}
void operator=(const float rhs) {
float32_t flt;
std::memcpy(&flt, &rhs, sizeof(flt));
*this = f32_to_extF80(flt);
*this = f32_to_extF80(FEXCore::BitCast<float32_t>(rhs));
}
void operator=(const double rhs) {
float64_t flt;
std::memcpy(&flt, &rhs, sizeof(flt));
*this = f64_to_extF80(flt);
*this = f64_to_extF80(FEXCore::BitCast<float64_t>(rhs));
}
void operator=(const int16_t rhs) {
@@ -236,21 +228,15 @@ struct X80SoftFloat {
}
X80SoftFloat(const float rhs) {
float32_t flt;
std::memcpy(&flt, &rhs, sizeof(float32_t));
*this = f32_to_extF80(flt);
*this = f32_to_extF80(FEXCore::BitCast<float32_t>(rhs));
}
X80SoftFloat(const double rhs) {
float64_t flt;
std::memcpy(&flt, &rhs, sizeof(float64_t));
*this = f64_to_extF80(flt);
*this = f64_to_extF80(FEXCore::BitCast<float64_t>(rhs));
}
X80SoftFloat(BIGFLOAT rhs) {
float128_t flt;
std::memcpy(&flt, &rhs, sizeof(float128_t));
*this = f128_to_extF80(flt);
*this = f128_to_extF80(FEXCore::BitCast<float128_t>(rhs));
}
X80SoftFloat(const int16_t rhs) {
+17
View File
@@ -6,6 +6,7 @@
#include <climits>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <type_traits>
namespace FEXCore {
@@ -61,4 +62,20 @@ template <typename T>
return trailing_zeroes + 1;
}
// Stand-in for std::bit_cast until libc++ implements it.
template <typename To, typename From>
[[nodiscard]] inline To BitCast(const From& source) noexcept
{
static_assert(sizeof(From) == sizeof(To),
"BitCast source and destination types must be equal in size.");
static_assert(std::is_trivially_copyable_v<From>,
"BitCast source type must be trivially copyable.");
static_assert(std::is_trivially_copyable_v<To>,
"BitCast destination type must be trivially copyable.");
std::aligned_storage_t<sizeof(To), alignof(To)> storage;
std::memcpy(&storage, &source, sizeof(storage));
return reinterpret_cast<To&>(storage);
}
} // namespace FEXCore