diff --git a/src/common/bit_set.h b/src/common/bit_set.h index 1e6b238bc..0f2c36ebf 100644 --- a/src/common/bit_set.h +++ b/src/common/bit_set.h @@ -2,78 +2,14 @@ #pragma once +#include #include -#ifdef _WIN32 -#include -#endif #include -#include #include #include "common/common_types.h" -// namespace avoids conflict with OS X Carbon; don't use BitSet directly namespace Common { -// Helper functions: - -#ifdef _MSC_VER -template -static inline int CountSetBits(T v) { - // from https://graphics.stanford.edu/~seander/bithacks.html - // GCC has this built in, but MSVC's intrinsic will only emit the actual - // POPCNT instruction, which we're not depending on - v = v - ((v >> 1) & (T) ~(T)0 / 3); - v = (v & (T) ~(T)0 / 15 * 3) + ((v >> 2) & (T) ~(T)0 / 15 * 3); - v = (v + (v >> 4)) & (T) ~(T)0 / 255 * 15; - return (T)(v * ((T) ~(T)0 / 255)) >> (sizeof(T) - 1) * 8; -} -static inline int LeastSignificantSetBit(u8 val) { - unsigned long index; - _BitScanForward(&index, val); - return (int)index; -} -static inline int LeastSignificantSetBit(u16 val) { - unsigned long index; - _BitScanForward(&index, val); - return (int)index; -} -static inline int LeastSignificantSetBit(u32 val) { - unsigned long index; - _BitScanForward(&index, val); - return (int)index; -} -static inline int LeastSignificantSetBit(u64 val) { - unsigned long index; - _BitScanForward64(&index, val); - return (int)index; -} -#else -static inline int CountSetBits(u8 val) { - return __builtin_popcount(val); -} -static inline int CountSetBits(u16 val) { - return __builtin_popcount(val); -} -static inline int CountSetBits(u32 val) { - return __builtin_popcount(val); -} -static inline int CountSetBits(u64 val) { - return __builtin_popcountll(val); -} -static inline int LeastSignificantSetBit(u8 val) { - return __builtin_ctz(val); -} -static inline int LeastSignificantSetBit(u16 val) { - return __builtin_ctz(val); -} -static inline int LeastSignificantSetBit(u32 val) { - return __builtin_ctz(val); -} -static inline int LeastSignificantSetBit(u64 val) { - return __builtin_ctzll(val); -} -#endif - // Similar to std::bitset, this is a class which encapsulates a bitset, i.e. // using the set bits of an integer to represent a set of integers. Like that // class, it acts like an array of bools: @@ -93,9 +29,8 @@ static inline int LeastSignificantSetBit(u64 val) { // - Counting set bits using .Count() - see comment on that method. template + requires std::is_unsigned_v class BitSet { - static_assert(!std::is_signed_v, "BitSet should not be used with signed types"); - public: // A reference to a particular bit, returned from operator[]. class Ref { @@ -122,7 +57,7 @@ public: constexpr Iterator(IntTy val) : m_val(val) {} constexpr int operator*() { // This will never be called when m_val == 0, because that would be the end() iterator - return LeastSignificantSetBit(m_val); + return std::countr_zero(m_val); } constexpr Iterator& operator++() { // Unset least significant set bit @@ -200,13 +135,8 @@ public: constexpr operator bool() { return m_val != 0; } - - // Warning: Even though on modern CPUs this is a single fast instruction, - // Dolphin's official builds do not currently assume POPCNT support on x86, - // so slower explicit bit twiddling is generated. Still should generally - // be faster than a loop. constexpr u32 Count() const { - return CountSetBits(m_val); + return std::popcount(m_val); } constexpr Iterator begin() const { diff --git a/src/core/hle/service/cecd/cecd.cpp b/src/core/hle/service/cecd/cecd.cpp index 5d5f37ef8..0fd17aa18 100644 --- a/src/core/hle/service/cecd/cecd.cpp +++ b/src/core/hle/service/cecd/cecd.cpp @@ -1,7 +1,7 @@ // Copyright 2015 Citra Emulator Project // Licensed under GPLv2 or any later version // Refer to the license.txt file included. - +#pragma optimize("", off) #include #include #include