mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-06 15:00:17 +02:00
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:
1 parent
cba4ca7d01
commit
e369626929
2 files changed
+27
-24
No files matched your search
+10
-24
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
Reference in new issue
Block a user