diff --git a/rpcs3/util/atomic.cpp b/rpcs3/util/atomic.cpp index 8005c97f51..b3bbc7bb15 100644 --- a/rpcs3/util/atomic.cpp +++ b/rpcs3/util/atomic.cpp @@ -1391,7 +1391,7 @@ bool atomic_wait_engine::raw_notify(const void* data, u64 thread_id) { for (u64 bits = s_cond_bits[i / 64]; bits; bits &= bits - 1) { - utils::prefetch_read(s_cond_list + i + std::countl_zero(bits)); + utils::prefetch_read(s_cond_list + i + std::countr_zero(bits)); } } diff --git a/rpcs3/util/atomic.hpp b/rpcs3/util/atomic.hpp index 1a874be975..c1746214be 100644 --- a/rpcs3/util/atomic.hpp +++ b/rpcs3/util/atomic.hpp @@ -72,24 +72,25 @@ namespace atomic_wait __m128i mask; template - constexpr void set_value(T value) + static constexpr __m128i get_value(T value = T{}) { static_assert((sizeof(T) & (sizeof(T) - 1)) == 0); static_assert(sizeof(T) <= 16); if constexpr (sizeof(T) <= 8) { - old = _mm_cvtsi64_si128(std::bit_cast, T>(value)); + return _mm_cvtsi64_si128(std::bit_cast, T>(value)); } else if constexpr (sizeof(T) == 16) { - old = std::bit_cast<__m128i>(value); + return std::bit_cast<__m128i>(value); } } - void set_value() + template + constexpr void set_value(T value = T{}) { - old = _mm_setzero_si128(); + old = get_value(); } template @@ -108,9 +109,23 @@ namespace atomic_wait } } - void set_mask() + template + constexpr void set_mask() { - mask = _mm_set1_epi64x(-1); + mask = get_mask(); + } + + template + static constexpr __m128i get_mask() + { + if constexpr (sizeof(T) <= 8) + { + return _mm_cvtsi64_si128(UINT64_MAX >> ((64 - sizeof(T) * 8) & 63)); + } + else + { + return _mm_set1_epi64x(-1); + } } }; @@ -131,7 +146,7 @@ namespace atomic_wait template constexpr list(atomic_t&... vars) - : m_info{{&vars.raw(), sizeof(U), _mm_setzero_si128(), _mm_set1_epi64x(-1)}...} + : m_info{{&vars.raw(), sizeof(U), info::get_value(), info::get_mask()}...} { static_assert(sizeof...(U) <= Max); } @@ -164,7 +179,7 @@ namespace atomic_wait m_info[Index].data = &var.raw(); m_info[Index].size = sizeof(T2) | (static_cast(Flags) << 8); m_info[Index].template set_value(value); - m_info[Index].mask = _mm_set1_epi64x(-1); + m_info[Index].template set_mask(); } template @@ -1447,7 +1462,7 @@ public: // Overload with mask (only selected bits are checked), timeout is discouraged template - void wait(type old_value, type mask_value, atomic_wait_timeout timeout = atomic_wait_timeout::inf) + void wait(type old_value, type mask_value, atomic_wait_timeout timeout = atomic_wait_timeout::inf) const noexcept { if constexpr (sizeof(T) <= 8) {