1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-22 02:32:36 +01:00

Implement std::bit_cast<>

Partial implementation of std::bit_cast from C++20.
Also fix most strict-aliasing rule break warnings (gcc).
This commit is contained in:
Nekotekina 2019-06-02 00:12:17 +03:00
parent 790962425c
commit dfd50d0185
24 changed files with 145 additions and 176 deletions

View File

@ -380,13 +380,12 @@ struct se_storage<T, 2, 2>
static inline u16 to(const T& src)
{
return swap(reinterpret_cast<const u16&>(src));
return swap(std::bit_cast<u16>(src));
}
static inline T from(u16 src)
{
const u16 result = swap(src);
return reinterpret_cast<const T&>(result);
return std::bit_cast<T, u16>(swap(src));
}
};
@ -406,13 +405,12 @@ struct se_storage<T, 4, 4>
static inline u32 to(const T& src)
{
return swap(reinterpret_cast<const u32&>(src));
return swap(std::bit_cast<u32>(src));
}
static inline T from(u32 src)
{
const u32 result = swap(src);
return reinterpret_cast<const T&>(result);
return std::bit_cast<T, u32>(swap(src));
}
};
@ -432,13 +430,12 @@ struct se_storage<T, 8, 8>
static inline u64 to(const T& src)
{
return swap(reinterpret_cast<const u64&>(src));
return swap(std::bit_cast<u64>(src));
}
static inline T from(u64 src)
{
const u64 result = swap(src);
return reinterpret_cast<const T&>(result);
return std::bit_cast<T, u64>(swap(src));
}
};
@ -454,13 +451,12 @@ struct se_storage<T, 16, 16>
static inline v128 to(const T& src)
{
return swap(reinterpret_cast<const v128&>(src));
return swap(std::bit_cast<v128>(src));
}
static inline T from(const v128& src)
{
const v128 result = swap(src);
return reinterpret_cast<const T&>(result);
return std::bit_cast<T, v128>(swap(src));
}
};
@ -524,33 +520,24 @@ class se_t<T, false, Align>
stype m_data;
static stype init(type value)
{
stype result;
std::memcpy(&result, &value, sizeof(result));
return result;
}
public:
se_t() = default;
se_t(type value)
: m_data(init(value))
: m_data(std::bit_cast<stype>(value))
{
}
type value() const
{
type result;
std::memcpy(&result, &m_data, sizeof(result));
return result;
return std::bit_cast<type>(m_data);
}
se_t& operator=(const se_t& value) = default;
se_t& operator=(type value)
{
std::memcpy(&m_data, &value, sizeof(m_data));
m_data = std::bit_cast<stype>(value);
return *this;
}

View File

@ -177,13 +177,13 @@ void fmt_class_string<ullong>::format(std::string& out, u64 arg)
template <>
void fmt_class_string<float>::format(std::string& out, u64 arg)
{
fmt::append(out, "%gf", static_cast<float>(reinterpret_cast<f64&>(arg)));
fmt::append(out, "%gf", static_cast<float>(std::bit_cast<f64>(arg)));
}
template <>
void fmt_class_string<double>::format(std::string& out, u64 arg)
{
fmt::append(out, "%g", reinterpret_cast<f64&>(arg));
fmt::append(out, "%g", std::bit_cast<f64>(arg));
}
template <>

View File

@ -86,13 +86,13 @@ void patch_engine::append(const std::string& patch)
case patch_type::bef32:
case patch_type::lef32:
{
info.value_as<f32>() = patch[2].as<f32>();
info.value = std::bit_cast<u32>(patch[2].as<f32>());
break;
}
case patch_type::bef64:
case patch_type::lef64:
{
info.value_as<f64>() = patch[2].as<f64>();
info.value = std::bit_cast<u64>(patch[2].as<f64>());
break;
}
default:

View File

@ -28,12 +28,6 @@ class patch_engine
patch_type type;
u32 offset;
u64 value;
template <typename T>
T& value_as()
{
return *reinterpret_cast<T*>(reinterpret_cast<char*>(&value));
}
};
// Database

View File

@ -68,13 +68,13 @@ public:
// Get current "push" position
u32 size() const
{
return reinterpret_cast<const atomic_t<u32>&>(m_ctrl).load(); // Hack
return m_ctrl.load().push;
}
// Acquire the place for one or more elements.
u32 push_begin(u32 count = 1)
{
return reinterpret_cast<atomic_t<u32>&>(m_ctrl).fetch_add(count); // Hack
return std::bit_cast<atomic_t<u64>*>(&m_ctrl)->fetch_add(count); // Hack
}
// Get current "pop" position

View File

@ -84,6 +84,22 @@
#define AUDIT(...) ((void)0)
#endif
#if defined(__cpp_lib_bit_cast) && (__cpp_lib_bit_cast >= 201806L)
#include <bit>
#else
namespace std
{
template <class To, class From, typename = std::enable_if_t<sizeof(To) == sizeof(From)>>
constexpr To bit_cast(const From& from) noexcept
{
static_assert(sizeof(To) == sizeof(From), "std::bit_cast<>: incompatible type size");
To result;
std::memcpy(&result, &from, sizeof(From));
return result;
}
}
#endif
using schar = signed char;
using uchar = unsigned char;
@ -387,15 +403,7 @@ union alignas(2) f16
(((_u16 & 0x7c00) + 0x1C000) << 13) | // Exponent ( exp - 15 + 127)
((_u16 & 0x03FF) << 13); // Mantissa
union
{
char data[4];
u32 data32;
f32 res;
};
data32 = raw;
return res;
return std::bit_cast<f32>(raw);
}
};
@ -410,23 +418,12 @@ constexpr T align(const T& value, ullong align)
template <typename T, typename T2>
inline u32 offset32(T T2::*const mptr)
{
union
{
char data[sizeof(std::size_t)];
std::size_t data_;
u32 data32;
};
#ifdef _MSC_VER
static_assert(sizeof(mptr) == sizeof(u32), "Invalid pointer-to-member size");
std::memcpy(data, &mptr, sizeof(u32));
return data32;
return std::bit_cast<u32>(mptr);
#elif __GNUG__
static_assert(sizeof(mptr) == sizeof(std::size_t), "Invalid pointer-to-member size");
std::memcpy(data, &mptr, sizeof(std::size_t));
return data_;
return std::bit_cast<std::size_t>(mptr);
#else
static_assert(sizeof(mptr) == 0, "Invalid pointer-to-member size");
static_assert(sizeof(mptr) == 0, "Unsupported pointer-to-member size");
#endif
}

View File

@ -12,13 +12,5 @@ enum FPSCR_RN
// Get the exponent of a float
inline int fexpf(float x)
{
union
{
char data[4];
u32 data32;
float arg;
};
arg = x;
return (data32 >> 23) & 0xFF;
return (std::bit_cast<u32>(x) >> 23) & 0xff;
}

View File

@ -58,8 +58,7 @@ struct ps3_fmt_src
template <>
f64 ps3_fmt_src::get<f64>(std::size_t index) const
{
const u64 value = get<u64>(index);
return *reinterpret_cast<const f64*>(reinterpret_cast<const u8*>(&value));
return std::bit_cast<f64>(get<u64>(index));
}
static std::string ps3_fmt(ppu_thread& context, vm::cptr<char> fmt, u32 g_count)

View File

@ -774,7 +774,7 @@ bool ppu_interpreter_precise::VCTSXS(ppu_thread& ppu, ppu_opcode_t op)
const f32 X = b._f[i];
const bool sign = std::signbit(X);
const u8 exp = (u8)fexpf(X);
const u32 frac = (u32&)X << 9;
const u32 frac = std::bit_cast<u32>(X) << 9;
const s16 exp2 = exp + uim - 127;
if (exp == 255)
@ -827,7 +827,7 @@ bool ppu_interpreter_precise::VCTUXS(ppu_thread& ppu, ppu_opcode_t op)
const f32 X = b._f[i];
const bool sign = std::signbit(X);
const u8 exp = (u8)fexpf(X);
const u32 frac = (u32&)X << 9;
const u32 frac = std::bit_cast<u32>(X) << 9;
const s16 exp2 = exp + uim - 127;
if (exp == 255)
@ -4326,7 +4326,7 @@ bool ppu_interpreter::EXTSB(ppu_thread& ppu, ppu_opcode_t op)
bool ppu_interpreter::STFIWX(ppu_thread& ppu, ppu_opcode_t op)
{
const u64 addr = op.ra ? ppu.gpr[op.ra] + ppu.gpr[op.rb] : ppu.gpr[op.rb];
vm::write32(vm::cast(addr, HERE), (u32)(u64&)ppu.fpr[op.frs]);
vm::write32(vm::cast(addr, HERE), std::bit_cast<u64>(ppu.fpr[op.frs]));
return true;
}
@ -4699,7 +4699,7 @@ bool ppu_interpreter::MTFSFI(ppu_thread& ppu, ppu_opcode_t op)
bool ppu_interpreter::MFFS(ppu_thread& ppu, ppu_opcode_t op)
{
LOG_WARNING(PPU, "MFFS");
(u64&)ppu.fpr[op.frd] = u64{ppu.fpscr.fl} << 15 | u64{ppu.fpscr.fg} << 14 | u64{ppu.fpscr.fe} << 13 | u64{ppu.fpscr.fu} << 12;
ppu.fpr[op.frd] = std::bit_cast<f64>(u64{ppu.fpscr.fl} << 15 | u64{ppu.fpscr.fg} << 14 | u64{ppu.fpscr.fe} << 13 | u64{ppu.fpscr.fu} << 12);
if (UNLIKELY(op.rc)) ppu_cr_set(ppu, 1, ppu.fpscr.fg, ppu.fpscr.fl, ppu.fpscr.fe, ppu.fpscr.fu);
return true;
}
@ -4718,7 +4718,7 @@ bool ppu_interpreter::FCMPU(ppu_thread& ppu, ppu_opcode_t op)
u8 test_fu = ppu.fpscr.fg = a > b;
test_fu |= ppu.fpscr.fl = a < b;
test_fu |= ppu.fpscr.fe = a == b;
(u8&)ppu.fpscr.fu = test_fu ^ 1;
ppu.fpscr.fu = std::bit_cast<bool, u8>(test_fu ^ 1);
ppu_cr_set(ppu, op.crfd, ppu.fpscr.fl, ppu.fpscr.fg, ppu.fpscr.fe, ppu.fpscr.fu);
return true;
}
@ -4732,14 +4732,14 @@ bool ppu_interpreter::FRSP(ppu_thread& ppu, ppu_opcode_t op)
bool ppu_interpreter::FCTIW(ppu_thread& ppu, ppu_opcode_t op)
{
(s64&)ppu.fpr[op.frd] = _mm_cvtsd_si32(_mm_load_sd(&ppu.fpr[op.frb]));
ppu.fpr[op.frd] = std::bit_cast<f64, s64>(_mm_cvtsd_si32(_mm_load_sd(&ppu.fpr[op.frb])));
if (UNLIKELY(op.rc)) fmt::throw_exception("%s: op.rc", __func__); //ppu_cr_set(ppu, 1, ppu.fpscr.fg, ppu.fpscr.fl, ppu.fpscr.fe, ppu.fpscr.fu);
return true;
}
bool ppu_interpreter::FCTIWZ(ppu_thread& ppu, ppu_opcode_t op)
{
(s64&)ppu.fpr[op.frd] = _mm_cvttsd_si32(_mm_load_sd(&ppu.fpr[op.frb]));
ppu.fpr[op.frd] = std::bit_cast<f64, s64>(_mm_cvttsd_si32(_mm_load_sd(&ppu.fpr[op.frb])));
if (UNLIKELY(op.rc)) fmt::throw_exception("%s: op.rc", __func__); //ppu_cr_set(ppu, 1, ppu.fpscr.fg, ppu.fpscr.fl, ppu.fpscr.fe, ppu.fpscr.fu);
return true;
}
@ -4856,21 +4856,21 @@ bool ppu_interpreter::FABS(ppu_thread& ppu, ppu_opcode_t op)
bool ppu_interpreter::FCTID(ppu_thread& ppu, ppu_opcode_t op)
{
(s64&)ppu.fpr[op.frd] = _mm_cvtsd_si64(_mm_load_sd(&ppu.fpr[op.frb]));
ppu.fpr[op.frd] = std::bit_cast<f64, s64>(_mm_cvtsd_si64(_mm_load_sd(&ppu.fpr[op.frb])));
if (UNLIKELY(op.rc)) fmt::throw_exception("%s: op.rc", __func__); //ppu_cr_set(ppu, 1, ppu.fpscr.fg, ppu.fpscr.fl, ppu.fpscr.fe, ppu.fpscr.fu);
return true;
}
bool ppu_interpreter::FCTIDZ(ppu_thread& ppu, ppu_opcode_t op)
{
(s64&)ppu.fpr[op.frd] = _mm_cvttsd_si64(_mm_load_sd(&ppu.fpr[op.frb]));
ppu.fpr[op.frd] = std::bit_cast<f64, s64>(_mm_cvttsd_si64(_mm_load_sd(&ppu.fpr[op.frb])));
if (UNLIKELY(op.rc)) fmt::throw_exception("%s: op.rc", __func__); //ppu_cr_set(ppu, 1, ppu.fpscr.fg, ppu.fpscr.fl, ppu.fpscr.fe, ppu.fpscr.fu);
return true;
}
bool ppu_interpreter::FCFID(ppu_thread& ppu, ppu_opcode_t op)
{
_mm_store_sd(&ppu.fpr[op.frd], _mm_cvtsi64_sd(_mm_setzero_pd(), (s64&)ppu.fpr[op.frb]));
_mm_store_sd(&ppu.fpr[op.frd], _mm_cvtsi64_sd(_mm_setzero_pd(), std::bit_cast<s64>(ppu.fpr[op.frb])));
if (UNLIKELY(op.rc)) fmt::throw_exception("%s: op.rc", __func__); //ppu_cr_set(ppu, 1, ppu.fpscr.fg, ppu.fpscr.fl, ppu.fpscr.fe, ppu.fpscr.fu);
return true;
}

View File

@ -1000,8 +1000,8 @@ bool spu_interpreter_fast::FM(spu_thread& spu, spu_opcode_t op)
//check for extended
const auto nan_check = _mm_cmpeq_ps(_mm_and_ps(primary_result, all_exp_bits), all_exp_bits);
const auto sign_mask = _mm_xor_ps(_mm_and_ps((__m128&)sign_bits, spu.gpr[op.ra].vf), _mm_and_ps((__m128&)sign_bits, spu.gpr[op.rb].vf));
const auto extended_result = _mm_or_ps(sign_mask, _mm_andnot_ps((__m128&)sign_bits, primary_result));
const auto sign_mask = _mm_xor_ps(_mm_and_ps(sign_bits, spu.gpr[op.ra].vf), _mm_and_ps(sign_bits, spu.gpr[op.rb].vf));
const auto extended_result = _mm_or_ps(sign_mask, _mm_andnot_ps(sign_bits, primary_result));
const auto final_extended = _mm_andnot_ps(denorm_operand_mask, extended_result);
//if nan, result = ext, else result = flushed
@ -1769,7 +1769,7 @@ bool spu_interpreter::MPYA(spu_thread& spu, spu_opcode_t op)
bool spu_interpreter_fast::FNMS(spu_thread& spu, spu_opcode_t op)
{
const u32 test_bits = 0x7f800000;
auto mask = _mm_set1_ps((f32&)test_bits);
auto mask = _mm_set1_ps(std::bit_cast<f32>(test_bits));
auto test_a = _mm_and_ps(spu.gpr[op.ra].vf, mask);
auto mask_a = _mm_cmpneq_ps(test_a, mask);
@ -1786,7 +1786,7 @@ bool spu_interpreter_fast::FNMS(spu_thread& spu, spu_opcode_t op)
bool spu_interpreter_fast::FMA(spu_thread& spu, spu_opcode_t op)
{
const u32 test_bits = 0x7f800000;
auto mask = _mm_set1_ps((f32&)test_bits);
auto mask = _mm_set1_ps(std::bit_cast<f32>(test_bits));
auto test_a = _mm_and_ps(spu.gpr[op.ra].vf, mask);
auto mask_a = _mm_cmpneq_ps(test_a, mask);
@ -1803,7 +1803,7 @@ bool spu_interpreter_fast::FMA(spu_thread& spu, spu_opcode_t op)
bool spu_interpreter_fast::FMS(spu_thread& spu, spu_opcode_t op)
{
const u32 test_bits = 0x7f800000;
auto mask = _mm_set1_ps((f32&)test_bits);
auto mask = _mm_set1_ps(std::bit_cast<f32>(test_bits));
auto test_a = _mm_and_ps(spu.gpr[op.ra].vf, mask);
auto mask_a = _mm_cmpneq_ps(test_a, mask);
@ -1838,20 +1838,20 @@ static void SetHostRoundingMode(u32 rn)
// Floating-point utility constants and functions
static const u32 FLOAT_MAX_NORMAL_I = 0x7F7FFFFF;
static const float& FLOAT_MAX_NORMAL = (float&)FLOAT_MAX_NORMAL_I;
static const f32 FLOAT_MAX_NORMAL = std::bit_cast<f32>(FLOAT_MAX_NORMAL_I);
static const u32 FLOAT_NAN_I = 0x7FC00000;
static const float& FLOAT_NAN = (float&)FLOAT_NAN_I;
static const f32 FLOAT_NAN = std::bit_cast<f32>(FLOAT_NAN_I);
static const u64 DOUBLE_NAN_I = 0x7FF8000000000000ULL;
static const double DOUBLE_NAN = (double&)DOUBLE_NAN_I;
static const f64 DOUBLE_NAN = std::bit_cast<f64>(DOUBLE_NAN_I);
inline bool issnan(double x)
{
return std::isnan(x) && ((s64&)x) << 12 > 0;
return std::isnan(x) && (std::bit_cast<s64>(x)) << 12 > 0;
}
inline bool issnan(float x)
{
return std::isnan(x) && ((s32&)x) << 9 > 0;
return std::isnan(x) && (std::bit_cast<s32>(x)) << 9 > 0;
}
inline bool isextended(float x)
@ -1862,14 +1862,14 @@ inline bool isextended(float x)
inline float extended(bool sign, u32 mantissa) // returns -1^sign * 2^127 * (1.mantissa)
{
u32 bits = sign << 31 | 0x7F800000 | mantissa;
return (float&)bits;
return std::bit_cast<f32>(bits);
}
inline float ldexpf_extended(float x, int exp) // ldexpf() for extended values, assumes result is in range
{
u32 bits = (u32&)x;
u32 bits = std::bit_cast<u32>(x);
if (bits << 1 != 0) bits += exp * 0x00800000;
return (float&)bits;
return std::bit_cast<f32>(bits);
}
inline bool isdenormal(float x)
@ -1979,8 +1979,8 @@ static void FA_FS(spu_thread& spu, spu_opcode_t op, bool sub)
{
if (std::signbit(a) != std::signbit(b))
{
const u32 bits = (u32&)a - 1;
result = (float&)bits;
const u32 bits = std::bit_cast<u32>(a) - 1;
result = std::bit_cast<f32>(bits);
}
else
@ -1990,8 +1990,8 @@ static void FA_FS(spu_thread& spu, spu_opcode_t op, bool sub)
{
if (std::signbit(a) != std::signbit(b))
{
const u32 bits = (u32&)b - 1;
result = (float&)bits;
const u32 bits = std::bit_cast<u32>(b) - 1;
result = std::bit_cast<f32>(bits);
}
else
result = b;
@ -2521,8 +2521,8 @@ static void FMA(spu_thread& spu, spu_opcode_t op, bool neg, bool sub)
result = new_a * new_b;
if (c != 0.0f && std::signbit(c) != sign)
{
u32 bits = (u32&)result - 1;
result = (float&)bits;
u32 bits = std::bit_cast<u32>(result) - 1;
result = std::bit_cast<f32>(bits);
}
}
else
@ -2552,8 +2552,8 @@ static void FMA(spu_thread& spu, spu_opcode_t op, bool neg, bool sub)
result = c;
if (sign != std::signbit(c))
{
u32 bits = (u32&)result - 1;
result = (float&)bits;
u32 bits = std::bit_cast<u32>(result) - 1;
result = std::bit_cast<f32>(bits);
}
}
else

View File

@ -373,10 +373,10 @@ namespace rsx
// Avoid byteswapping
auto tile = rsx->tiles[i].pack();
auto& tstate = tilestate.tiles[i];
tstate.tile = *reinterpret_cast<u32*>(&tile.tile);
tstate.limit = *reinterpret_cast<u32*>(&tile.limit);
tstate.pitch = rsx->tiles[i].binded ? *reinterpret_cast<u32*>(&tile.pitch) : 0;
tstate.format = rsx->tiles[i].binded ? *reinterpret_cast<u32*>(&tile.format) : 0;
tstate.tile = std::bit_cast<u32>(tile.tile);
tstate.limit = std::bit_cast<u32>(tile.limit);
tstate.pitch = rsx->tiles[i].binded ? std::bit_cast<u32>(tile.pitch) : 0;
tstate.format = rsx->tiles[i].binded ? std::bit_cast<u32>(tile.format) : 0;
}
for (u32 i = 0; i < limits::zculls_count; ++i)
@ -384,12 +384,12 @@ namespace rsx
// Avoid byteswapping
auto zc = rsx->zculls[i].pack();
auto& zcstate = tilestate.zculls[i];
zcstate.region = *reinterpret_cast<u32*>(&zc.region);
zcstate.size = *reinterpret_cast<u32*>(&zc.size);
zcstate.start = *reinterpret_cast<u32*>(&zc.start);
zcstate.offset = *reinterpret_cast<u32*>(&zc.offset);
zcstate.status0 = rsx->zculls[i].binded ? *reinterpret_cast<u32*>(&zc.status0) : 0;
zcstate.status1 = rsx->zculls[i].binded ? *reinterpret_cast<u32*>(&zc.status1) : 0;
zcstate.region = std::bit_cast<u32>(zc.region);
zcstate.size = std::bit_cast<u32>(zc.size);
zcstate.start = std::bit_cast<u32>(zc.start);
zcstate.offset = std::bit_cast<u32>(zc.offset);
zcstate.status0 = rsx->zculls[i].binded ? std::bit_cast<u32>(zc.status0) : 0;
zcstate.status1 = rsx->zculls[i].binded ? std::bit_cast<u32>(zc.status1) : 0;
}
const u64 tsnum = XXH64(&tilestate, sizeof(frame_capture_data::tile_state), 0);

View File

@ -77,7 +77,7 @@ std::string CgBinaryDisasm::AddConstDisAsm()
const u32 z = GetData(data[2]);
const u32 w = GetData(data[3]);
return fmt::format("{0x%08x(%g), 0x%08x(%g), 0x%08x(%g), 0x%08x(%g)}", x, (float&)x, y, (float&)y, z, (float&)z, w, (float&)w);
return fmt::format("{0x%08x(%g), 0x%08x(%g), 0x%08x(%g), 0x%08x(%g)}", x, std::bit_cast<f32>(x), y, std::bit_cast<f32>(y), z, std::bit_cast<f32>(z), w, std::bit_cast<f32>(w));
}
std::string CgBinaryDisasm::AddTexDisAsm()

View File

@ -906,7 +906,7 @@ void stream_vector(void *dst, u32 x, u32 y, u32 z, u32 w)
void stream_vector(void *dst, f32 x, f32 y, f32 z, f32 w)
{
stream_vector(dst, (u32&)x, (u32&)y, (u32&)z, (u32&)w);
stream_vector(dst, std::bit_cast<u32>(x), std::bit_cast<u32>(y), std::bit_cast<u32>(z), std::bit_cast<u32>(w));
}
void stream_vector_from_memory(void *dst, void *src)
{

View File

@ -221,7 +221,7 @@ std::string FragmentProgramDecompiler::AddConst()
u32 z = GetData(data[2]);
u32 w = GetData(data[3]);
const auto var = fmt::format("%s(%f, %f, %f, %f)", type, (f32&)x, (f32&)y, (f32&)z, (f32&)w);
const auto var = fmt::format("%s(%f, %f, %f, %f)", type, std::bit_cast<f32>(x), std::bit_cast<f32>(y), std::bit_cast<f32>(z), std::bit_cast<f32>(w));
return m_parr.AddParam(PF_PARAM_UNIFORM, type, name, var);
}

View File

@ -271,11 +271,11 @@ public:
bool test_and_set(f32 value, f32* dst) const
{
u32 hex = (u32&)value;
u32 hex = std::bit_cast<u32>(value);
if ((hex & 0x7FFFFFFF) == (hex_key & 0x7FFFFFFF))
{
hex = (hex & ~0x7FFFFFF) | hex_value;
*dst = (f32&)hex;
*dst = std::bit_cast<f32>(hex);
return true;
}
@ -560,14 +560,14 @@ public:
else if (sanitize)
{
//Convert NaNs and Infs to 0
const auto masked = _mm_and_si128((__m128i&)shuffled_vector, _mm_set1_epi32(0x7fffffff));
const auto masked = _mm_and_si128(shuffled_vector, _mm_set1_epi32(0x7fffffff));
const auto valid = _mm_cmplt_epi32(masked, _mm_set1_epi32(0x7f800000));
const auto result = _mm_and_si128((__m128i&)shuffled_vector, valid);
_mm_stream_si128((__m128i*)dst, (__m128i&)result);
const auto result = _mm_and_si128(shuffled_vector, valid);
_mm_stream_si128(std::bit_cast<__m128i*>(dst), result);
}
else
{
_mm_stream_si128((__m128i*)dst, shuffled_vector);
_mm_stream_si128(std::bit_cast<__m128i*>(dst), shuffled_vector);
}
dst += 4;

View File

@ -88,7 +88,7 @@ namespace gl
void clear_depth(GLfloat depth)
{
u32 value = (u32&)depth;
u32 value = std::bit_cast<u32>(depth);
if (!test_property(GL_DEPTH_CLEAR_VALUE, value))
{
glClearDepth(depth);
@ -107,7 +107,7 @@ namespace gl
void clear_stencil(GLint stencil)
{
u32 value = (u32&)stencil;
u32 value = std::bit_cast<u32>(stencil);
if (!test_property(GL_STENCIL_CLEAR_VALUE, value))
{
glClearStencil(stencil);
@ -152,8 +152,8 @@ namespace gl
void depth_bounds(float min, float max)
{
u32 depth_min = (u32&)min;
u32 depth_max = (u32&)max;
u32 depth_min = std::bit_cast<u32>(min);
u32 depth_max = std::bit_cast<u32>(max);
if (!test_property(DEPTH_BOUNDS_MIN, depth_min) || !test_property(DEPTH_BOUNDS_MAX, depth_max))
{
@ -166,8 +166,8 @@ namespace gl
void depth_range(float min, float max)
{
u32 depth_min = (u32&)min;
u32 depth_max = (u32&)max;
u32 depth_min = std::bit_cast<u32>(min);
u32 depth_max = std::bit_cast<u32>(max);
if (!test_property(DEPTH_RANGE_MIN, depth_min) || !test_property(DEPTH_RANGE_MAX, depth_max))
{
@ -189,7 +189,7 @@ namespace gl
void line_width(GLfloat width)
{
u32 value = (u32&)width;
u32 value = std::bit_cast<u32>(width);
if (!test_property(GL_LINE_WIDTH, value))
{
@ -218,8 +218,8 @@ namespace gl
void polygon_offset(float factor, float units)
{
u32 _units = (u32&)units;
u32 _factor = (u32&)factor;
u32 _units = std::bit_cast<u32>(units);
u32 _factor = std::bit_cast<u32>(factor);
if (!test_property(GL_POLYGON_OFFSET_UNITS, _units) || !test_property(GL_POLYGON_OFFSET_FACTOR, _factor))
{

View File

@ -135,7 +135,7 @@ struct driver_state
void clear_depth(GLfloat depth)
{
u32 value = (u32&)depth;
u32 value = std::bit_cast<u32>(depth);
if (!test_property(GL_DEPTH_CLEAR_VALUE, value))
{
glClearDepth(depth);
@ -154,7 +154,7 @@ struct driver_state
void clear_stencil(GLint stencil)
{
u32 value = (u32&)stencil;
u32 value = std::bit_cast<u32>(stencil);
if (!test_property(GL_STENCIL_CLEAR_VALUE, value))
{
glClearStencil(stencil);
@ -194,8 +194,8 @@ struct driver_state
void depth_bounds(float min, float max)
{
u32 depth_min = (u32&)min;
u32 depth_max = (u32&)max;
u32 depth_min = std::bit_cast<u32>(min);
u32 depth_max = std::bit_cast<u32>(max);
if (!test_property(DEPTH_BOUNDS_MIN, depth_min) || !test_property(DEPTH_BOUNDS_MAX, depth_max))
{
@ -208,8 +208,8 @@ struct driver_state
void depth_range(float min, float max)
{
u32 depth_min = (u32&)min;
u32 depth_max = (u32&)max;
u32 depth_min = std::bit_cast<u32>(min);
u32 depth_max = std::bit_cast<u32>(max);
if (!test_property(DEPTH_RANGE_MIN, depth_min) || !test_property(DEPTH_RANGE_MAX, depth_max))
{
@ -231,7 +231,7 @@ struct driver_state
void line_width(GLfloat width)
{
u32 value = (u32&)width;
u32 value = std::bit_cast<u32>(width);
if (!test_property(GL_LINE_WIDTH, value))
{
@ -260,8 +260,8 @@ struct driver_state
void polygon_offset(float factor, float units)
{
u32 _units = (u32&)units;
u32 _factor = (u32&)factor;
u32 _units = std::bit_cast<u32>(units);
u32 _factor = std::bit_cast<u32>(factor);
if (!test_property(GL_POLYGON_OFFSET_UNITS, _units) || !test_property(GL_POLYGON_OFFSET_FACTOR, _factor))
{

View File

@ -593,10 +593,10 @@ namespace rsx
float offset_z = rsx::method_registers.viewport_offset_z();
float one = 1.f;
stream_vector(buffer, (u32&)scale_x, 0, 0, (u32&)offset_x);
stream_vector((char*)buffer + 16, 0, (u32&)scale_y, 0, (u32&)offset_y);
stream_vector((char*)buffer + 32, 0, 0, (u32&)scale_z, (u32&)offset_z);
stream_vector((char*)buffer + 48, 0, 0, 0, (u32&)one);
stream_vector(buffer, std::bit_cast<u32>(scale_x), 0, 0, std::bit_cast<u32>(offset_x));
stream_vector((char*)buffer + 16, 0, std::bit_cast<u32>(scale_y), 0, std::bit_cast<u32>(offset_y));
stream_vector((char*)buffer + 32, 0, 0, std::bit_cast<u32>(scale_z), std::bit_cast<u32>(offset_z));
stream_vector((char*)buffer + 48, 0, 0, 0, std::bit_cast<u32>(one));
}
void thread::fill_user_clip_data(void *buffer) const
@ -708,8 +708,8 @@ namespace rsx
const f32 wpos_bias = (window_origin == rsx::window_origin::top) ? 0.f : window_height;
u32 *dst = static_cast<u32*>(buffer);
stream_vector(dst, (u32&)fog0, (u32&)fog1, rop_control, (u32&)alpha_ref);
stream_vector(dst + 4, alpha_func, fog_mode, (u32&)wpos_scale, (u32&)wpos_bias);
stream_vector(dst, std::bit_cast<u32>(fog0), std::bit_cast<u32>(fog1), rop_control, std::bit_cast<u32>(alpha_ref));
stream_vector(dst + 4, alpha_func, fog_mode, std::bit_cast<u32>(wpos_scale), std::bit_cast<u32>(wpos_bias));
}
void thread::fill_fragment_texture_parameters(void *buffer, const RSXFragmentProgram &fragment_program)
@ -1547,7 +1547,7 @@ namespace rsx
// TODO: Optionally add support for 16-bit formats (not necessary since type casts are easy with that)
u32 remap = tex.remap();
result.redirected_textures |= (1 << i);
result.texture_scale[i][2] = (f32&)remap;
result.texture_scale[i][2] = std::bit_cast<f32>(remap);
break;
}
case CELL_GCM_TEXTURE_DEPTH16:
@ -1598,7 +1598,7 @@ namespace rsx
#ifdef __APPLE__
texture_control |= (sampler_descriptors[i]->encoded_component_map() << 16);
#endif
result.texture_scale[i][3] = (f32&)texture_control;
result.texture_scale[i][3] = std::bit_cast<f32>(texture_control);
}
}
@ -1703,7 +1703,7 @@ namespace rsx
{
u32 remap = tex.remap();
result.redirected_textures |= (1 << i);
result.texture_scale[i][2] = (f32&)remap;
result.texture_scale[i][2] = std::bit_cast<f32>(remap);
break;
}
case CELL_GCM_TEXTURE_DEPTH16:

View File

@ -815,7 +815,7 @@ namespace vk
error_message = "Invalid external handle (VK_ERROR_INVALID_EXTERNAL_HANDLE_KHR)";
break;
default:
error_message = fmt::format("Unknown Code (%Xh, %d)%s", (s32)error_code, (s32&)error_code, faulting_addr);
error_message = fmt::format("Unknown Code (%Xh, %d)%s", static_cast<s32>(error_code), static_cast<s32>(error_code), faulting_addr);
break;
}

View File

@ -2144,7 +2144,7 @@ public:
break;
}
LOG_NOTICE(RSX, "Swapchain: present mode %d in use.", (s32&)swapchain_present_mode);
LOG_NOTICE(RSX, "Swapchain: present mode %d in use.", static_cast<int>(swapchain_present_mode));
uint32_t nb_swap_images = surface_descriptors.minImageCount + 1;
if (surface_descriptors.maxImageCount > 0)

View File

@ -797,7 +797,7 @@ namespace
std::string transform_constant(size_t index, u32 arg)
{
return "Transform constant " + std::to_string(index) + ": " + std::to_string(arg) + "/" +
std::to_string((float&)arg);
std::to_string(std::bit_cast<f32>(arg));
}
std::string texture_offset(size_t index, u32 arg)

View File

@ -1147,7 +1147,7 @@ struct registers_decoder<NV4097_SET_DEPTH_BOUNDS_MIN>
f32 depth_bound_min() const
{
return reinterpret_cast<const f32&>(m_data.depth_bound_min);
return std::bit_cast<f32, u32>(m_data.depth_bound_min);
}
};
@ -1173,7 +1173,7 @@ struct registers_decoder<NV4097_SET_DEPTH_BOUNDS_MAX>
f32 depth_bound_max() const
{
return reinterpret_cast<const f32&>(m_data.depth_bound_max);
return std::bit_cast<f32, u32>(m_data.depth_bound_max);
}
};
@ -1199,7 +1199,7 @@ struct registers_decoder<NV4097_SET_FOG_PARAMS>
f32 fog_param_0() const
{
return reinterpret_cast<const f32&>(m_data.fog_param_0);
return std::bit_cast<f32, u32>(m_data.fog_param_0);
}
};
@ -1225,7 +1225,7 @@ struct registers_decoder<NV4097_SET_FOG_PARAMS + 1>
f32 fog_param_1() const
{
return reinterpret_cast<const f32&>(m_data.fog_param_1);
return std::bit_cast<f32, u32>(m_data.fog_param_1);
}
};
@ -1251,7 +1251,7 @@ struct registers_decoder<NV4097_SET_CLIP_MIN>
f32 clip_min() const
{
return reinterpret_cast<const f32&>(m_data.clip_min);
return std::bit_cast<f32, u32>(m_data.clip_min);
}
};
@ -1277,7 +1277,7 @@ struct registers_decoder<NV4097_SET_CLIP_MAX>
f32 clip_max() const
{
return reinterpret_cast<const f32&>(m_data.clip_max);
return std::bit_cast<f32, u32>(m_data.clip_max);
}
};
@ -1303,7 +1303,7 @@ struct registers_decoder<NV4097_SET_POLYGON_OFFSET_SCALE_FACTOR>
f32 polygon_offset_scale_factor() const
{
return reinterpret_cast<const f32&>(m_data.polygon_offset_scale_factor);
return std::bit_cast<f32, u32>(m_data.polygon_offset_scale_factor);
}
};
@ -1329,7 +1329,7 @@ struct registers_decoder<NV4097_SET_POLYGON_OFFSET_BIAS>
f32 polygon_offset_scale_bias() const
{
return reinterpret_cast<const f32&>(m_data.polygon_offset_scale_bias);
return std::bit_cast<f32, u32>(m_data.polygon_offset_scale_bias);
}
};
@ -1355,7 +1355,7 @@ struct registers_decoder<NV4097_SET_VIEWPORT_SCALE>
f32 viewport_scale_x() const
{
return reinterpret_cast<const f32&>(m_data.viewport_scale_x);
return std::bit_cast<f32, u32>(m_data.viewport_scale_x);
}
};
@ -1381,7 +1381,7 @@ struct registers_decoder<NV4097_SET_VIEWPORT_SCALE + 1>
f32 viewport_scale_y() const
{
return reinterpret_cast<const f32&>(m_data.viewport_scale_y);
return std::bit_cast<f32, u32>(m_data.viewport_scale_y);
}
};
@ -1407,7 +1407,7 @@ struct registers_decoder<NV4097_SET_VIEWPORT_SCALE + 2>
f32 viewport_scale_z() const
{
return reinterpret_cast<const f32&>(m_data.viewport_scale_z);
return std::bit_cast<f32, u32>(m_data.viewport_scale_z);
}
};
@ -1433,7 +1433,7 @@ struct registers_decoder<NV4097_SET_VIEWPORT_SCALE + 3>
f32 viewport_scale_w() const
{
return reinterpret_cast<const f32&>(m_data.viewport_scale_w);
return std::bit_cast<f32, u32>(m_data.viewport_scale_w);
}
};
@ -1459,7 +1459,7 @@ struct registers_decoder<NV4097_SET_VIEWPORT_OFFSET>
f32 viewport_offset_x() const
{
return reinterpret_cast<const f32&>(m_data.viewport_offset_x);
return std::bit_cast<f32, u32>(m_data.viewport_offset_x);
}
};
@ -1485,7 +1485,7 @@ struct registers_decoder<NV4097_SET_VIEWPORT_OFFSET + 1>
f32 viewport_offset_y() const
{
return reinterpret_cast<const f32&>(m_data.viewport_offset_y);
return std::bit_cast<f32, u32>(m_data.viewport_offset_y);
}
};
@ -1511,7 +1511,7 @@ struct registers_decoder<NV4097_SET_VIEWPORT_OFFSET + 2>
f32 viewport_offset_z() const
{
return reinterpret_cast<const f32&>(m_data.viewport_offset_z);
return std::bit_cast<f32, u32>(m_data.viewport_offset_z);
}
};
@ -1537,7 +1537,7 @@ struct registers_decoder<NV4097_SET_VIEWPORT_OFFSET + 3>
f32 viewport_offset_w() const
{
return reinterpret_cast<const f32&>(m_data.viewport_offset_w);
return std::bit_cast<f32, u32>(m_data.viewport_offset_w);
}
};
@ -3509,7 +3509,7 @@ struct registers_decoder<NV4097_SET_POINT_SIZE>
f32 point_size() const
{
return (f32&)m_data.raw_data;
return std::bit_cast<f32>(m_data.raw_data);
}
};
@ -4450,7 +4450,7 @@ struct transform_constant_helper
f32 constant_value() const
{
return reinterpret_cast<const f32&>(m_data.raw_value);
return std::bit_cast<f32>(m_data.raw_value);
}
};
@ -4690,7 +4690,7 @@ struct register_vertex_printer<f32, count>
static std::string value(u32 v)
{
return std::to_string(reinterpret_cast<f32&>(v));
return std::to_string(std::bit_cast<f32>(v));
}
};

View File

@ -147,7 +147,7 @@ void register_editor_dialog::OnOkay(const std::shared_ptr<cpu_thread>& _cpu)
{
const ullong reg_value = std::stoull(value.substr(16, 31), 0, 16);
if (reg.compare(0, 3, "GPR") == 0) ppu.gpr[reg_index] = (u64)reg_value;
if (reg.compare(0, 3, "FPR") == 0) (u64&)ppu.fpr[reg_index] = (u64)reg_value;
if (reg.compare(0, 3, "FPR") == 0) ppu.fpr[reg_index] = std::bit_cast<f64>(reg_value);
return;
}
if (reg.compare(0, 2, "VR") == 0)

View File

@ -440,7 +440,7 @@ namespace
{
be_t<u32> stored_val = as_const_span<const be_t<u32>>(orig_buffer)[idx];
u32 swapped_val = stored_val;
f32 float_val = (f32&)swapped_val;
f32 float_val = std::bit_cast<f32>(swapped_val);
u8 val = float_val * 255.f;
return{ val, val, val };
}