summaryrefslogtreecommitdiff
path: root/Source/Core/Common/BitUtils.h
diff options
context:
space:
mode:
authorJMC47 <JMC4789@gmail.com>2022-07-10 17:27:47 -0400
committerGitHub <noreply@github.com>2022-07-10 17:27:47 -0400
commit38cb76dea54b59fa0eae458e0898edebed13e7ca (patch)
tree75c3f91c49e0198ee60195b8f21f158bbdb1f1ac /Source/Core/Common/BitUtils.h
parent6e09b13ce361e9f560033234908565f7afa6f090 (diff)
parent0d947ed6fe21e51e2081418fa048c95b1ef66a97 (diff)
Merge pull request #10807 from merryhime/LogicalImm
Arm64Emitter: Simplify LogicalImm logic
Diffstat (limited to 'Source/Core/Common/BitUtils.h')
-rw-r--r--Source/Core/Common/BitUtils.h50
1 files changed, 50 insertions, 0 deletions
diff --git a/Source/Core/Common/BitUtils.h b/Source/Core/Common/BitUtils.h
index 1934809e21..bd0801491d 100644
--- a/Source/Core/Common/BitUtils.h
+++ b/Source/Core/Common/BitUtils.h
@@ -411,6 +411,56 @@ constexpr int CountLeadingZeros(uint32_t value)
#endif
}
+template <typename T>
+constexpr int CountTrailingZerosConst(T value)
+{
+ int result = sizeof(T) * 8;
+ while (value)
+ {
+ result--;
+ value <<= 1;
+ }
+ return result;
+}
+
+constexpr int CountTrailingZeros(uint64_t value)
+{
+#if defined(__GNUC__)
+ return value ? __builtin_ctzll(value) : 64;
+#elif defined(_MSC_VER)
+ if (std::is_constant_evaluated())
+ {
+ return CountTrailingZerosConst(value);
+ }
+ else
+ {
+ unsigned long index = 0;
+ return _BitScanForward64(&index, value) ? index : 64;
+ }
+#else
+ return CountTrailingZerosConst(value);
+#endif
+}
+
+constexpr int CountTrailingZeros(uint32_t value)
+{
+#if defined(__GNUC__)
+ return value ? __builtin_ctz(value) : 32;
+#elif defined(_MSC_VER)
+ if (std::is_constant_evaluated())
+ {
+ return CountTrailingZerosConst(value);
+ }
+ else
+ {
+ unsigned long index = 0;
+ return _BitScanForward(&index, value) ? index : 32;
+ }
+#else
+ return CountLeadingZerosConst(value);
+#endif
+}
+
#undef CONSTEXPR_FROM_INTRINSIC
template <typename T>