From dfd50d01854af53e7d787cfbe6a9dfb15dfe90a3 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Sun, 2 Jun 2019 00:12:17 +0300 Subject: [PATCH] Implement std::bit_cast<> Partial implementation of std::bit_cast from C++20. Also fix most strict-aliasing rule break warnings (gcc). --- Utilities/BEType.h | 35 +++++---------- Utilities/StrFmt.cpp | 4 +- Utilities/bin_patch.cpp | 4 +- Utilities/bin_patch.h | 6 --- Utilities/lockless.h | 4 +- Utilities/types.h | 43 +++++++++---------- rpcs3/Emu/Cell/Common.h | 10 +---- rpcs3/Emu/Cell/Modules/sys_libc_.cpp | 3 +- rpcs3/Emu/Cell/PPUInterpreter.cpp | 20 ++++----- rpcs3/Emu/Cell/SPUInterpreter.cpp | 42 +++++++++--------- rpcs3/Emu/RSX/Capture/rsx_capture.cpp | 20 ++++----- rpcs3/Emu/RSX/CgBinaryFragmentProgram.cpp | 4 +- rpcs3/Emu/RSX/Common/BufferUtils.cpp | 2 +- .../RSX/Common/FragmentProgramDecompiler.cpp | 2 +- rpcs3/Emu/RSX/Common/ProgramStateCache.h | 12 +++--- rpcs3/Emu/RSX/GL/GLExecutionState.h | 18 ++++---- rpcs3/Emu/RSX/GL/GLGSRender.h | 18 ++++---- rpcs3/Emu/RSX/RSXThread.cpp | 20 ++++----- rpcs3/Emu/RSX/VK/VKHelpers.cpp | 4 +- rpcs3/Emu/RSX/VK/VKHelpers.h | 4 +- rpcs3/Emu/RSX/gcm_printing.cpp | 2 +- rpcs3/Emu/RSX/rsx_decode.h | 40 ++++++++--------- rpcs3/rpcs3qt/register_editor_dialog.cpp | 2 +- rpcs3/rpcs3qt/rsx_debugger.cpp | 2 +- 24 files changed, 145 insertions(+), 176 deletions(-) diff --git a/Utilities/BEType.h b/Utilities/BEType.h index e9e73a4ee5..0e9367bcd9 100644 --- a/Utilities/BEType.h +++ b/Utilities/BEType.h @@ -380,13 +380,12 @@ struct se_storage static inline u16 to(const T& src) { - return swap(reinterpret_cast(src)); + return swap(std::bit_cast(src)); } static inline T from(u16 src) { - const u16 result = swap(src); - return reinterpret_cast(result); + return std::bit_cast(swap(src)); } }; @@ -406,13 +405,12 @@ struct se_storage static inline u32 to(const T& src) { - return swap(reinterpret_cast(src)); + return swap(std::bit_cast(src)); } static inline T from(u32 src) { - const u32 result = swap(src); - return reinterpret_cast(result); + return std::bit_cast(swap(src)); } }; @@ -432,13 +430,12 @@ struct se_storage static inline u64 to(const T& src) { - return swap(reinterpret_cast(src)); + return swap(std::bit_cast(src)); } static inline T from(u64 src) { - const u64 result = swap(src); - return reinterpret_cast(result); + return std::bit_cast(swap(src)); } }; @@ -454,13 +451,12 @@ struct se_storage static inline v128 to(const T& src) { - return swap(reinterpret_cast(src)); + return swap(std::bit_cast(src)); } static inline T from(const v128& src) { - const v128 result = swap(src); - return reinterpret_cast(result); + return std::bit_cast(swap(src)); } }; @@ -524,33 +520,24 @@ class se_t 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(value)) { } type value() const { - type result; - std::memcpy(&result, &m_data, sizeof(result)); - return result; + return std::bit_cast(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(value); return *this; } diff --git a/Utilities/StrFmt.cpp b/Utilities/StrFmt.cpp index 7aff3bd877..d8e85cfdcb 100644 --- a/Utilities/StrFmt.cpp +++ b/Utilities/StrFmt.cpp @@ -177,13 +177,13 @@ void fmt_class_string::format(std::string& out, u64 arg) template <> void fmt_class_string::format(std::string& out, u64 arg) { - fmt::append(out, "%gf", static_cast(reinterpret_cast(arg))); + fmt::append(out, "%gf", static_cast(std::bit_cast(arg))); } template <> void fmt_class_string::format(std::string& out, u64 arg) { - fmt::append(out, "%g", reinterpret_cast(arg)); + fmt::append(out, "%g", std::bit_cast(arg)); } template <> diff --git a/Utilities/bin_patch.cpp b/Utilities/bin_patch.cpp index 926620645a..b578f03aad 100644 --- a/Utilities/bin_patch.cpp +++ b/Utilities/bin_patch.cpp @@ -86,13 +86,13 @@ void patch_engine::append(const std::string& patch) case patch_type::bef32: case patch_type::lef32: { - info.value_as() = patch[2].as(); + info.value = std::bit_cast(patch[2].as()); break; } case patch_type::bef64: case patch_type::lef64: { - info.value_as() = patch[2].as(); + info.value = std::bit_cast(patch[2].as()); break; } default: diff --git a/Utilities/bin_patch.h b/Utilities/bin_patch.h index 40212633ea..562db18ba0 100644 --- a/Utilities/bin_patch.h +++ b/Utilities/bin_patch.h @@ -28,12 +28,6 @@ class patch_engine patch_type type; u32 offset; u64 value; - - template - T& value_as() - { - return *reinterpret_cast(reinterpret_cast(&value)); - } }; // Database diff --git a/Utilities/lockless.h b/Utilities/lockless.h index 90f20475ea..18c5f2f7d1 100644 --- a/Utilities/lockless.h +++ b/Utilities/lockless.h @@ -68,13 +68,13 @@ public: // Get current "push" position u32 size() const { - return reinterpret_cast&>(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&>(m_ctrl).fetch_add(count); // Hack + return std::bit_cast*>(&m_ctrl)->fetch_add(count); // Hack } // Get current "pop" position diff --git a/Utilities/types.h b/Utilities/types.h index 4afabdf508..892ff6eae2 100644 --- a/Utilities/types.h +++ b/Utilities/types.h @@ -84,6 +84,22 @@ #define AUDIT(...) ((void)0) #endif +#if defined(__cpp_lib_bit_cast) && (__cpp_lib_bit_cast >= 201806L) +#include +#else +namespace std +{ + template > + 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(raw); } }; @@ -410,23 +418,12 @@ constexpr T align(const T& value, ullong align) template 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(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(mptr); #else - static_assert(sizeof(mptr) == 0, "Invalid pointer-to-member size"); + static_assert(sizeof(mptr) == 0, "Unsupported pointer-to-member size"); #endif } diff --git a/rpcs3/Emu/Cell/Common.h b/rpcs3/Emu/Cell/Common.h index d67c35a5e6..59960aa816 100644 --- a/rpcs3/Emu/Cell/Common.h +++ b/rpcs3/Emu/Cell/Common.h @@ -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(x) >> 23) & 0xff; } diff --git a/rpcs3/Emu/Cell/Modules/sys_libc_.cpp b/rpcs3/Emu/Cell/Modules/sys_libc_.cpp index 4f8ccb61fe..8249367a2d 100644 --- a/rpcs3/Emu/Cell/Modules/sys_libc_.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_libc_.cpp @@ -58,8 +58,7 @@ struct ps3_fmt_src template <> f64 ps3_fmt_src::get(std::size_t index) const { - const u64 value = get(index); - return *reinterpret_cast(reinterpret_cast(&value)); + return std::bit_cast(get(index)); } static std::string ps3_fmt(ppu_thread& context, vm::cptr fmt, u32 g_count) diff --git a/rpcs3/Emu/Cell/PPUInterpreter.cpp b/rpcs3/Emu/Cell/PPUInterpreter.cpp index 3462ffa41e..0efc68092e 100644 --- a/rpcs3/Emu/Cell/PPUInterpreter.cpp +++ b/rpcs3/Emu/Cell/PPUInterpreter.cpp @@ -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(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(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(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(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(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(_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(_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(_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(_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(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; } diff --git a/rpcs3/Emu/Cell/SPUInterpreter.cpp b/rpcs3/Emu/Cell/SPUInterpreter.cpp index 574650487a..cd3cfa6301 100644 --- a/rpcs3/Emu/Cell/SPUInterpreter.cpp +++ b/rpcs3/Emu/Cell/SPUInterpreter.cpp @@ -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(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(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(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(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(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(DOUBLE_NAN_I); inline bool issnan(double x) { - return std::isnan(x) && ((s64&)x) << 12 > 0; + return std::isnan(x) && (std::bit_cast(x)) << 12 > 0; } inline bool issnan(float x) { - return std::isnan(x) && ((s32&)x) << 9 > 0; + return std::isnan(x) && (std::bit_cast(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(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(x); if (bits << 1 != 0) bits += exp * 0x00800000; - return (float&)bits; + return std::bit_cast(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(a) - 1; + result = std::bit_cast(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(b) - 1; + result = std::bit_cast(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(result) - 1; + result = std::bit_cast(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(result) - 1; + result = std::bit_cast(bits); } } else diff --git a/rpcs3/Emu/RSX/Capture/rsx_capture.cpp b/rpcs3/Emu/RSX/Capture/rsx_capture.cpp index bcf10edcfe..7cc3721d2a 100644 --- a/rpcs3/Emu/RSX/Capture/rsx_capture.cpp +++ b/rpcs3/Emu/RSX/Capture/rsx_capture.cpp @@ -373,10 +373,10 @@ namespace rsx // Avoid byteswapping auto tile = rsx->tiles[i].pack(); auto& tstate = tilestate.tiles[i]; - tstate.tile = *reinterpret_cast(&tile.tile); - tstate.limit = *reinterpret_cast(&tile.limit); - tstate.pitch = rsx->tiles[i].binded ? *reinterpret_cast(&tile.pitch) : 0; - tstate.format = rsx->tiles[i].binded ? *reinterpret_cast(&tile.format) : 0; + tstate.tile = std::bit_cast(tile.tile); + tstate.limit = std::bit_cast(tile.limit); + tstate.pitch = rsx->tiles[i].binded ? std::bit_cast(tile.pitch) : 0; + tstate.format = rsx->tiles[i].binded ? std::bit_cast(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(&zc.region); - zcstate.size = *reinterpret_cast(&zc.size); - zcstate.start = *reinterpret_cast(&zc.start); - zcstate.offset = *reinterpret_cast(&zc.offset); - zcstate.status0 = rsx->zculls[i].binded ? *reinterpret_cast(&zc.status0) : 0; - zcstate.status1 = rsx->zculls[i].binded ? *reinterpret_cast(&zc.status1) : 0; + zcstate.region = std::bit_cast(zc.region); + zcstate.size = std::bit_cast(zc.size); + zcstate.start = std::bit_cast(zc.start); + zcstate.offset = std::bit_cast(zc.offset); + zcstate.status0 = rsx->zculls[i].binded ? std::bit_cast(zc.status0) : 0; + zcstate.status1 = rsx->zculls[i].binded ? std::bit_cast(zc.status1) : 0; } const u64 tsnum = XXH64(&tilestate, sizeof(frame_capture_data::tile_state), 0); diff --git a/rpcs3/Emu/RSX/CgBinaryFragmentProgram.cpp b/rpcs3/Emu/RSX/CgBinaryFragmentProgram.cpp index e846a30284..f0896065dd 100644 --- a/rpcs3/Emu/RSX/CgBinaryFragmentProgram.cpp +++ b/rpcs3/Emu/RSX/CgBinaryFragmentProgram.cpp @@ -34,7 +34,7 @@ void CgBinaryDisasm::AddCodeAsm(const std::string& code) case RSX_FP_OPCODE_LOOP: case RSX_FP_OPCODE_NOP: case RSX_FP_OPCODE_REP: - case RSX_FP_OPCODE_RET: + case RSX_FP_OPCODE_RET: m_dst_reg_name.clear(); op_name = rsx_fp_op_names[m_opcode] + std::string(dst.fp16 ? "H" : "R"); break; @@ -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(x), y, std::bit_cast(y), z, std::bit_cast(z), w, std::bit_cast(w)); } std::string CgBinaryDisasm::AddTexDisAsm() diff --git a/rpcs3/Emu/RSX/Common/BufferUtils.cpp b/rpcs3/Emu/RSX/Common/BufferUtils.cpp index 02c4a22075..0d4df42225 100644 --- a/rpcs3/Emu/RSX/Common/BufferUtils.cpp +++ b/rpcs3/Emu/RSX/Common/BufferUtils.cpp @@ -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(x), std::bit_cast(y), std::bit_cast(z), std::bit_cast(w)); } void stream_vector_from_memory(void *dst, void *src) { diff --git a/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp b/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp index 8433ca6a98..31710fd744 100644 --- a/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp +++ b/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp @@ -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(x), std::bit_cast(y), std::bit_cast(z), std::bit_cast(w)); return m_parr.AddParam(PF_PARAM_UNIFORM, type, name, var); } diff --git a/rpcs3/Emu/RSX/Common/ProgramStateCache.h b/rpcs3/Emu/RSX/Common/ProgramStateCache.h index cb432306f4..88271e2c8f 100644 --- a/rpcs3/Emu/RSX/Common/ProgramStateCache.h +++ b/rpcs3/Emu/RSX/Common/ProgramStateCache.h @@ -271,11 +271,11 @@ public: bool test_and_set(f32 value, f32* dst) const { - u32 hex = (u32&)value; + u32 hex = std::bit_cast(value); if ((hex & 0x7FFFFFFF) == (hex_key & 0x7FFFFFFF)) { hex = (hex & ~0x7FFFFFF) | hex_value; - *dst = (f32&)hex; + *dst = std::bit_cast(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; diff --git a/rpcs3/Emu/RSX/GL/GLExecutionState.h b/rpcs3/Emu/RSX/GL/GLExecutionState.h index 03249d67d0..25040492b6 100644 --- a/rpcs3/Emu/RSX/GL/GLExecutionState.h +++ b/rpcs3/Emu/RSX/GL/GLExecutionState.h @@ -88,7 +88,7 @@ namespace gl void clear_depth(GLfloat depth) { - u32 value = (u32&)depth; + u32 value = std::bit_cast(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(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(min); + u32 depth_max = std::bit_cast(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(min); + u32 depth_max = std::bit_cast(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(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(units); + u32 _factor = std::bit_cast(factor); if (!test_property(GL_POLYGON_OFFSET_UNITS, _units) || !test_property(GL_POLYGON_OFFSET_FACTOR, _factor)) { diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.h b/rpcs3/Emu/RSX/GL/GLGSRender.h index 2917597c04..dfca56e1d3 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.h +++ b/rpcs3/Emu/RSX/GL/GLGSRender.h @@ -135,7 +135,7 @@ struct driver_state void clear_depth(GLfloat depth) { - u32 value = (u32&)depth; + u32 value = std::bit_cast(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(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(min); + u32 depth_max = std::bit_cast(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(min); + u32 depth_max = std::bit_cast(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(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(units); + u32 _factor = std::bit_cast(factor); if (!test_property(GL_POLYGON_OFFSET_UNITS, _units) || !test_property(GL_POLYGON_OFFSET_FACTOR, _factor)) { diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 4e4176aa7e..9615a73d84 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -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(scale_x), 0, 0, std::bit_cast(offset_x)); + stream_vector((char*)buffer + 16, 0, std::bit_cast(scale_y), 0, std::bit_cast(offset_y)); + stream_vector((char*)buffer + 32, 0, 0, std::bit_cast(scale_z), std::bit_cast(offset_z)); + stream_vector((char*)buffer + 48, 0, 0, 0, std::bit_cast(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(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(fog0), std::bit_cast(fog1), rop_control, std::bit_cast(alpha_ref)); + stream_vector(dst + 4, alpha_func, fog_mode, std::bit_cast(wpos_scale), std::bit_cast(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(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(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(remap); break; } case CELL_GCM_TEXTURE_DEPTH16: @@ -2138,7 +2138,7 @@ namespace rsx m_flattener.force_disable(); } - if (emu_flip) + if (emu_flip) { async_flip_requested.clear(flip_request::emu_requested); } diff --git a/rpcs3/Emu/RSX/VK/VKHelpers.cpp b/rpcs3/Emu/RSX/VK/VKHelpers.cpp index 17eb86f07a..eb3d47daec 100644 --- a/rpcs3/Emu/RSX/VK/VKHelpers.cpp +++ b/rpcs3/Emu/RSX/VK/VKHelpers.cpp @@ -352,7 +352,7 @@ namespace vk { info.usage = usage; CHECK_RESULT(vkCreateBuffer(*g_current_renderer, &info, nullptr, &tmp)); - + vkGetBufferMemoryRequirements(*g_current_renderer, tmp, &memory_reqs); if (g_current_renderer->get_compatible_memory_type(memory_reqs.memoryTypeBits, memory_flags, nullptr)) { @@ -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(error_code), static_cast(error_code), faulting_addr); break; } diff --git a/rpcs3/Emu/RSX/VK/VKHelpers.h b/rpcs3/Emu/RSX/VK/VKHelpers.h index 6294a7310b..b0e9cb32de 100644 --- a/rpcs3/Emu/RSX/VK/VKHelpers.h +++ b/rpcs3/Emu/RSX/VK/VKHelpers.h @@ -232,7 +232,7 @@ namespace vk private: }; - // Memory Allocator - Vulkan Memory Allocator + // Memory Allocator - Vulkan Memory Allocator // https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator class mem_allocator_vma : public mem_allocator_base @@ -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(swapchain_present_mode)); uint32_t nb_swap_images = surface_descriptors.minImageCount + 1; if (surface_descriptors.maxImageCount > 0) diff --git a/rpcs3/Emu/RSX/gcm_printing.cpp b/rpcs3/Emu/RSX/gcm_printing.cpp index ab223c8ecf..2bec16154d 100644 --- a/rpcs3/Emu/RSX/gcm_printing.cpp +++ b/rpcs3/Emu/RSX/gcm_printing.cpp @@ -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(arg)); } std::string texture_offset(size_t index, u32 arg) diff --git a/rpcs3/Emu/RSX/rsx_decode.h b/rpcs3/Emu/RSX/rsx_decode.h index 2f9355093b..d226d0cc13 100644 --- a/rpcs3/Emu/RSX/rsx_decode.h +++ b/rpcs3/Emu/RSX/rsx_decode.h @@ -1147,7 +1147,7 @@ struct registers_decoder f32 depth_bound_min() const { - return reinterpret_cast(m_data.depth_bound_min); + return std::bit_cast(m_data.depth_bound_min); } }; @@ -1173,7 +1173,7 @@ struct registers_decoder f32 depth_bound_max() const { - return reinterpret_cast(m_data.depth_bound_max); + return std::bit_cast(m_data.depth_bound_max); } }; @@ -1199,7 +1199,7 @@ struct registers_decoder f32 fog_param_0() const { - return reinterpret_cast(m_data.fog_param_0); + return std::bit_cast(m_data.fog_param_0); } }; @@ -1225,7 +1225,7 @@ struct registers_decoder f32 fog_param_1() const { - return reinterpret_cast(m_data.fog_param_1); + return std::bit_cast(m_data.fog_param_1); } }; @@ -1251,7 +1251,7 @@ struct registers_decoder f32 clip_min() const { - return reinterpret_cast(m_data.clip_min); + return std::bit_cast(m_data.clip_min); } }; @@ -1277,7 +1277,7 @@ struct registers_decoder f32 clip_max() const { - return reinterpret_cast(m_data.clip_max); + return std::bit_cast(m_data.clip_max); } }; @@ -1303,7 +1303,7 @@ struct registers_decoder f32 polygon_offset_scale_factor() const { - return reinterpret_cast(m_data.polygon_offset_scale_factor); + return std::bit_cast(m_data.polygon_offset_scale_factor); } }; @@ -1329,7 +1329,7 @@ struct registers_decoder f32 polygon_offset_scale_bias() const { - return reinterpret_cast(m_data.polygon_offset_scale_bias); + return std::bit_cast(m_data.polygon_offset_scale_bias); } }; @@ -1355,7 +1355,7 @@ struct registers_decoder f32 viewport_scale_x() const { - return reinterpret_cast(m_data.viewport_scale_x); + return std::bit_cast(m_data.viewport_scale_x); } }; @@ -1381,7 +1381,7 @@ struct registers_decoder f32 viewport_scale_y() const { - return reinterpret_cast(m_data.viewport_scale_y); + return std::bit_cast(m_data.viewport_scale_y); } }; @@ -1407,7 +1407,7 @@ struct registers_decoder f32 viewport_scale_z() const { - return reinterpret_cast(m_data.viewport_scale_z); + return std::bit_cast(m_data.viewport_scale_z); } }; @@ -1433,7 +1433,7 @@ struct registers_decoder f32 viewport_scale_w() const { - return reinterpret_cast(m_data.viewport_scale_w); + return std::bit_cast(m_data.viewport_scale_w); } }; @@ -1459,7 +1459,7 @@ struct registers_decoder f32 viewport_offset_x() const { - return reinterpret_cast(m_data.viewport_offset_x); + return std::bit_cast(m_data.viewport_offset_x); } }; @@ -1485,7 +1485,7 @@ struct registers_decoder f32 viewport_offset_y() const { - return reinterpret_cast(m_data.viewport_offset_y); + return std::bit_cast(m_data.viewport_offset_y); } }; @@ -1511,7 +1511,7 @@ struct registers_decoder f32 viewport_offset_z() const { - return reinterpret_cast(m_data.viewport_offset_z); + return std::bit_cast(m_data.viewport_offset_z); } }; @@ -1537,7 +1537,7 @@ struct registers_decoder f32 viewport_offset_w() const { - return reinterpret_cast(m_data.viewport_offset_w); + return std::bit_cast(m_data.viewport_offset_w); } }; @@ -3509,7 +3509,7 @@ struct registers_decoder f32 point_size() const { - return (f32&)m_data.raw_data; + return std::bit_cast(m_data.raw_data); } }; @@ -3604,7 +3604,7 @@ struct registers_decoder { if (is_depth_stencil) return m_data.clear_z24; - + return m_data.clear_z16; } }; @@ -4450,7 +4450,7 @@ struct transform_constant_helper f32 constant_value() const { - return reinterpret_cast(m_data.raw_value); + return std::bit_cast(m_data.raw_value); } }; @@ -4690,7 +4690,7 @@ struct register_vertex_printer static std::string value(u32 v) { - return std::to_string(reinterpret_cast(v)); + return std::to_string(std::bit_cast(v)); } }; diff --git a/rpcs3/rpcs3qt/register_editor_dialog.cpp b/rpcs3/rpcs3qt/register_editor_dialog.cpp index 263d312907..cdcb4a075e 100644 --- a/rpcs3/rpcs3qt/register_editor_dialog.cpp +++ b/rpcs3/rpcs3qt/register_editor_dialog.cpp @@ -147,7 +147,7 @@ void register_editor_dialog::OnOkay(const std::shared_ptr& _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(reg_value); return; } if (reg.compare(0, 2, "VR") == 0) diff --git a/rpcs3/rpcs3qt/rsx_debugger.cpp b/rpcs3/rpcs3qt/rsx_debugger.cpp index c3c6fe1fc0..db58234dd0 100644 --- a/rpcs3/rpcs3qt/rsx_debugger.cpp +++ b/rpcs3/rpcs3qt/rsx_debugger.cpp @@ -440,7 +440,7 @@ namespace { be_t stored_val = as_const_span>(orig_buffer)[idx]; u32 swapped_val = stored_val; - f32 float_val = (f32&)swapped_val; + f32 float_val = std::bit_cast(swapped_val); u8 val = float_val * 255.f; return{ val, val, val }; }