summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/bit_util.h45
-rw-r--r--src/tests/CMakeLists.txt1
-rw-r--r--src/tests/common/bit_utils.cpp42
3 files changed, 76 insertions, 12 deletions
diff --git a/src/common/bit_util.h b/src/common/bit_util.h
index 14e53c273..70e728a5e 100644
--- a/src/common/bit_util.h
+++ b/src/common/bit_util.h
@@ -59,22 +59,43 @@ inline u64 CountLeadingZeroes64(u64 value) {
59} 59}
60#endif 60#endif
61 61
62
63#ifdef _MSC_VER
62inline u32 CountTrailingZeroes32(u32 value) { 64inline u32 CountTrailingZeroes32(u32 value) {
63 u32 count = 0; 65 unsigned long trailing_zero = 0;
64 while (((value >> count) & 0xf) == 0 && count < 32) 66
65 count += 4; 67 if (_BitScanForward(&trailing_zero, value) != 0) {
66 while (((value >> count) & 1) == 0 && count < 32) 68 return trailing_zero;
67 count++; 69 }
68 return count; 70
71 return 32;
69} 72}
70 73
71inline u64 CountTrailingZeroes64(u64 value) { 74inline u64 CountTrailingZeroes64(u64 value) {
72 u64 count = 0; 75 unsigned long trailing_zero = 0;
73 while (((value >> count) & 0xf) == 0 && count < 64) 76
74 count += 4; 77 if (_BitScanForward64(&trailing_zero, value) != 0) {
75 while (((value >> count) & 1) == 0 && count < 64) 78 return trailing_zero;
76 count++; 79 }
77 return count; 80
81 return 64;
78} 82}
83#else
84inline u32 CountTrailingZeroes32(u32 value) {
85 if (value == 0) {
86 return 32;
87 }
88
89 return __builtin_ctz(value);
90}
91
92inline u64 CountTrailingZeroes64(u64 value) {
93 if (value == 0) {
94 return 64;
95 }
96
97 return __builtin_ctzll(value);
98}
99#endif
79 100
80} // namespace Common 101} // namespace Common
diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt
index d0284bdf4..f38267be8 100644
--- a/src/tests/CMakeLists.txt
+++ b/src/tests/CMakeLists.txt
@@ -1,5 +1,6 @@
1add_executable(tests 1add_executable(tests
2 common/bit_field.cpp 2 common/bit_field.cpp
3 common/bit_utils.cpp
3 common/param_package.cpp 4 common/param_package.cpp
4 common/ring_buffer.cpp 5 common/ring_buffer.cpp
5 core/arm/arm_test_common.cpp 6 core/arm/arm_test_common.cpp
diff --git a/src/tests/common/bit_utils.cpp b/src/tests/common/bit_utils.cpp
new file mode 100644
index 000000000..77c17c526
--- /dev/null
+++ b/src/tests/common/bit_utils.cpp
@@ -0,0 +1,42 @@
1// Copyright 2017 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <catch2/catch.hpp>
6#include <math.h>
7#include "common/bit_util.h"
8
9namespace Common {
10
11inline u32 CTZ32(u32 value) {
12 u32 count = 0;
13 while (((value >> count) & 0xf) == 0 && count < 32)
14 count += 4;
15 while (((value >> count) & 1) == 0 && count < 32)
16 count++;
17 return count;
18}
19
20inline u64 CTZ64(u64 value) {
21 u64 count = 0;
22 while (((value >> count) & 0xf) == 0 && count < 64)
23 count += 4;
24 while (((value >> count) & 1) == 0 && count < 64)
25 count++;
26 return count;
27}
28
29
30TEST_CASE("BitUtils", "[common]") {
31 REQUIRE(Common::CountTrailingZeroes32(0) == CTZ32(0));
32 REQUIRE(Common::CountTrailingZeroes64(0) == CTZ64(0));
33 REQUIRE(Common::CountTrailingZeroes32(9) == CTZ32(9));
34 REQUIRE(Common::CountTrailingZeroes32(8) == CTZ32(8));
35 REQUIRE(Common::CountTrailingZeroes32(0x801000) == CTZ32(0x801000));
36 REQUIRE(Common::CountTrailingZeroes64(9) == CTZ64(9));
37 REQUIRE(Common::CountTrailingZeroes64(8) == CTZ64(8));
38 REQUIRE(Common::CountTrailingZeroes64(0x801000) == CTZ64(0x801000));
39 REQUIRE(Common::CountTrailingZeroes64(0x801000000000UL) == CTZ64(0x801000000000UL));
40}
41
42} // namespace Common