summaryrefslogtreecommitdiff
path: root/src/common/bit_util.h
diff options
context:
space:
mode:
authorGravatar Lioncash2021-01-21 03:48:32 -0500
committerGravatar Lioncash2021-01-21 04:07:58 -0500
commit6ff2db181f3dc8a9c95f6f9564c0bb1db7cae8e3 (patch)
treed6e0ba300638e038f5f2b343f9a779abd5d4a198 /src/common/bit_util.h
parentMerge pull request #5360 from ReinUsesLisp/enforce-memclass-access (diff)
downloadyuzu-6ff2db181f3dc8a9c95f6f9564c0bb1db7cae8e3.tar.gz
yuzu-6ff2db181f3dc8a9c95f6f9564c0bb1db7cae8e3.tar.xz
yuzu-6ff2db181f3dc8a9c95f6f9564c0bb1db7cae8e3.zip
bit_util: Unify implementations of MostSignificantBit32/MostSignificantBit64
We can use the standardized CLZ facilities to perform this. This also allows us to make utilizing functions constexpr and eliminate the inclusion of an intrinsics header.
Diffstat (limited to '')
-rw-r--r--src/common/bit_util.h48
1 files changed, 13 insertions, 35 deletions
diff --git a/src/common/bit_util.h b/src/common/bit_util.h
index 685e7fc9b..69fb4e5e4 100644
--- a/src/common/bit_util.h
+++ b/src/common/bit_util.h
@@ -7,10 +7,6 @@
7#include <climits> 7#include <climits>
8#include <cstddef> 8#include <cstddef>
9 9
10#ifdef _MSC_VER
11#include <intrin.h>
12#endif
13
14#include "common/common_types.h" 10#include "common/common_types.h"
15 11
16namespace Common { 12namespace Common {
@@ -21,48 +17,30 @@ template <typename T>
21 return sizeof(T) * CHAR_BIT; 17 return sizeof(T) * CHAR_BIT;
22} 18}
23 19
24#ifdef _MSC_VER 20[[nodiscard]] constexpr u32 MostSignificantBit32(const u32 value) {
25 21 return 31U - static_cast<u32>(std::countl_zero(value));
26[[nodiscard]] inline u32 MostSignificantBit32(const u32 value) {
27 unsigned long result;
28 _BitScanReverse(&result, value);
29 return static_cast<u32>(result);
30}
31
32[[nodiscard]] inline u32 MostSignificantBit64(const u64 value) {
33 unsigned long result;
34 _BitScanReverse64(&result, value);
35 return static_cast<u32>(result);
36}
37
38#else
39
40[[nodiscard]] inline u32 MostSignificantBit32(const u32 value) {
41 return 31U - static_cast<u32>(__builtin_clz(value));
42} 22}
43 23
44[[nodiscard]] inline u32 MostSignificantBit64(const u64 value) { 24[[nodiscard]] constexpr u32 MostSignificantBit64(const u64 value) {
45 return 63U - static_cast<u32>(__builtin_clzll(value)); 25 return 63U - static_cast<u32>(std::countl_zero(value));
46} 26}
47 27
48#endif 28[[nodiscard]] constexpr u32 Log2Floor32(const u32 value) {
49
50[[nodiscard]] inline u32 Log2Floor32(const u32 value) {
51 return MostSignificantBit32(value); 29 return MostSignificantBit32(value);
52} 30}
53 31
54[[nodiscard]] inline u32 Log2Ceil32(const u32 value) { 32[[nodiscard]] constexpr u32 Log2Floor64(const u64 value) {
55 const u32 log2_f = Log2Floor32(value); 33 return MostSignificantBit64(value);
56 return log2_f + ((value ^ (1U << log2_f)) != 0U);
57} 34}
58 35
59[[nodiscard]] inline u32 Log2Floor64(const u64 value) { 36[[nodiscard]] constexpr u32 Log2Ceil32(const u32 value) {
60 return MostSignificantBit64(value); 37 const u32 log2_f = Log2Floor32(value);
38 return log2_f + static_cast<u32>((value ^ (1U << log2_f)) != 0U);
61} 39}
62 40
63[[nodiscard]] inline u32 Log2Ceil64(const u64 value) { 41[[nodiscard]] constexpr u32 Log2Ceil64(const u64 value) {
64 const u64 log2_f = static_cast<u64>(Log2Floor64(value)); 42 const u64 log2_f = Log2Floor64(value);
65 return static_cast<u32>(log2_f + ((value ^ (1ULL << log2_f)) != 0ULL)); 43 return static_cast<u32>(log2_f + static_cast<u64>((value ^ (1ULL << log2_f)) != 0ULL));
66} 44}
67 45
68} // namespace Common 46} // namespace Common