diff --git a/Utilities/BitField.h b/Utilities/BitField.h index da41049193..55b2513a09 100644 --- a/Utilities/BitField.h +++ b/Utilities/BitField.h @@ -15,6 +15,9 @@ struct bf_base using vtype = std::common_type_t; using utype = typename std::make_unsigned::type; + static constexpr bool can_be_packed = N < (sizeof(int) * 8 + (std::is_unsigned_v ? 1 : 0)) && sizeof(vtype) > sizeof(int); + using compact_type = std::conditional_t, uint, int>, vtype>; + // Datatype bitsize static constexpr uint bitmax = sizeof(T) * 8; static_assert(N - 1 < bitmax, "bf_base<> error: N out of bounds"); @@ -38,6 +41,7 @@ struct bf_t : bf_base using type = typename bf_t::type; using vtype = typename bf_t::vtype; using utype = typename bf_t::utype; + using compact_type = typename bf_t::compact_type; // Field offset static constexpr uint bitpos = I; static_assert(bitpos + N <= bf_t::bitmax, "bf_t<> error: I out of bounds"); @@ -48,47 +52,29 @@ struct bf_t : bf_base return static_cast(static_cast(bf_t::mask1 >> (bf_t::bitmax - bf_t::bitsize)) << bitpos); } - // Bitfield extraction helper - template - struct extract_impl - { - static_assert(!sizeof(T2), "bf_t<> error: Invalid type"); - }; - - template - struct extract_impl::value>> - { - // Load unsigned value - static constexpr T2 extract(const T& data) - { - return static_cast((static_cast(data) >> bitpos) & bf_t::vmask); - } - }; - - template - struct extract_impl::value>> - { - // Load signed value (sign-extended) - static constexpr T2 extract(const T& data) - { - return static_cast(static_cast(static_cast(data) << (bf_t::bitmax - bitpos - N)) >> (bf_t::bitmax - N)); - } - }; - // Bitfield extraction - static constexpr vtype extract(const T& data) + static constexpr compact_type extract(const T& data) noexcept { - return extract_impl::extract(data); + if constexpr (std::is_signed_v) + { + // Load signed value (sign-extended) + return static_cast(static_cast(static_cast(data) << (bf_t::bitmax - bitpos - N)) >> (bf_t::bitmax - N)); + } + else + { + // Load unsigned value + return static_cast((static_cast(data) >> bitpos) & bf_t::vmask); + } } // Bitfield insertion - static constexpr vtype insert(vtype value) + static constexpr vtype insert(compact_type value) { return static_cast((value & bf_t::vmask) << bitpos); } // Load bitfield value - constexpr operator vtype() const + constexpr operator compact_type() const noexcept { return extract(this->m_data); } @@ -100,72 +86,72 @@ struct bf_t : bf_base } // Optimized bool conversion (must be removed if inappropriate) - explicit constexpr operator bool() const + explicit constexpr operator bool() const noexcept { return unshifted() != 0u; } // Store bitfield value - bf_t& operator =(vtype value) + bf_t& operator =(compact_type value) noexcept { this->m_data = static_cast((this->m_data & ~data_mask()) | insert(value)); return *this; } - vtype operator ++(int) + compact_type operator ++(int) { - utype result = *this; - *this = static_cast(result + 1); + compact_type result = *this; + *this = static_cast(result + 1u); return result; } bf_t& operator ++() { - return *this = *this + 1; + return *this = static_cast(*this + 1u); } - vtype operator --(int) + compact_type operator --(int) { - utype result = *this; - *this = static_cast(result - 1); + compact_type result = *this; + *this = static_cast(result - 1u); return result; } bf_t& operator --() { - return *this = *this - 1; + return *this = static_cast(*this - 1u); } - bf_t& operator +=(vtype right) + bf_t& operator +=(compact_type right) { - return *this = *this + right; + return *this = static_cast(*this + right); } - bf_t& operator -=(vtype right) + bf_t& operator -=(compact_type right) { - return *this = *this - right; + return *this = static_cast(*this - right); } - bf_t& operator *=(vtype right) + bf_t& operator *=(compact_type right) { - return *this = *this * right; + return *this = static_cast(*this * right); } - bf_t& operator &=(vtype right) + bf_t& operator &=(compact_type right) { - this->m_data &= static_cast(((static_cast(right) & bf_t::vmask) << bitpos) | ~(bf_t::vmask << bitpos)); + this->m_data &= static_cast(((static_cast(right + 0u) & bf_t::vmask) << bitpos) | ~(bf_t::vmask << bitpos)); return *this; } - bf_t& operator |=(vtype right) + bf_t& operator |=(compact_type right) { - this->m_data |= static_cast((static_cast(right) & bf_t::vmask) << bitpos); + this->m_data |= static_cast((static_cast(right + 0u) & bf_t::vmask) << bitpos); return *this; } - bf_t& operator ^=(vtype right) + bf_t& operator ^=(compact_type right) { - this->m_data ^= static_cast((static_cast(right) & bf_t::vmask) << bitpos); + this->m_data ^= static_cast((static_cast(right + 0u) & bf_t::vmask) << bitpos); return *this; } }; @@ -177,6 +163,7 @@ struct cf_t : bf_base::bitsize> using type = typename cf_t::type; using vtype = typename cf_t::vtype; using utype = typename cf_t::utype; + using compact_type = typename cf_t::compact_type; // Get disjunction of all "data" masks of concatenated values static constexpr vtype data_mask() @@ -185,25 +172,25 @@ struct cf_t : bf_base::bitsize> } // Extract all bitfields and concatenate - static constexpr vtype extract(const type& data) + static constexpr compact_type extract(const type& data) { - return static_cast(static_cast(F::extract(data)) << cf_t::bitsize | cf_t::extract(data)); + return static_cast(static_cast(F::extract(data)) << cf_t::bitsize | cf_t::extract(data)); } // Split bitfields and insert them - static constexpr vtype insert(vtype value) + static constexpr vtype insert(compact_type value) { return static_cast(F::insert(value >> cf_t::bitsize) | cf_t::insert(value)); } // Load value - constexpr operator vtype() const + constexpr operator compact_type() const noexcept { return extract(this->m_data); } // Store value - cf_t& operator =(vtype value) + cf_t& operator =(compact_type value) noexcept { this->m_data = (this->m_data & ~data_mask()) | insert(value); return *this; @@ -249,7 +236,7 @@ struct ff_t : bf_base } // Get value - operator vtype() const + constexpr operator vtype() const noexcept { return V; } diff --git a/rpcs3/Emu/Memory/vm.cpp b/rpcs3/Emu/Memory/vm.cpp index c545a60dff..3b2ee3fe89 100644 --- a/rpcs3/Emu/Memory/vm.cpp +++ b/rpcs3/Emu/Memory/vm.cpp @@ -570,7 +570,7 @@ namespace vm } addr2 += size3; - size2 -= size3; + size2 -= static_cast(size3); } return 0; diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index c8bc3c9528..809a09f889 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -339,10 +339,12 @@ namespace rsx max_result_by_division = std::max(max_result_by_division, max); // Discard lower frequencies because it has been proven that there are indices higher than them - freq_count -= frequencies + freq_count - std::remove_if(frequencies, frequencies + freq_count, [&max_result_by_division](u32 freq) + const usz discard_cnt = frequencies + freq_count - std::remove_if(frequencies, frequencies + freq_count, [&max_result_by_division](u32 freq) { return freq <= max_result_by_division; }); + + freq_count -= static_cast(discard_cnt); } } }