1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
From 881ceef5adda6f1cc5f5a9a15ae74b068bf85dd4 Mon Sep 17 00:00:00 2001
From: Michael Forney <mforney@mforney.org>
Date: Fri, 30 Apr 2021 18:45:18 -0700
Subject: [PATCH] Add portable fallback for ctz, clz, and clzll
---
include/common/attributes.h | 27 +++++++++++++++++++++++++--
1 file changed, 25 insertions(+), 2 deletions(-)
diff --git a/include/common/attributes.h b/include/common/attributes.h
index 4ccc421..72d5202 100644
--- a/include/common/attributes.h
+++ b/include/common/attributes.h
@@ -32,6 +32,7 @@
#include <stddef.h>
#include <assert.h>
+#include <strings.h>
#ifndef __has_attribute
#define __has_attribute(x) 0
@@ -156,7 +157,7 @@ static inline int clzll(const unsigned long long mask) {
return clz((unsigned)mask) + 32;
}
#endif /* _WIN64 */
-#else /* !_MSC_VER */
+#elif defined(__GNUC__)
static inline int ctz(const unsigned int mask) {
return __builtin_ctz(mask);
}
@@ -168,7 +169,29 @@ static inline int clz(const unsigned int mask) {
static inline int clzll(const unsigned long long mask) {
return __builtin_clzll(mask);
}
-#endif /* !_MSC_VER */
+#else /* __GNUC__ */
+static inline int ctz(const unsigned int mask) {
+ return ffs(mask) - 1;
+}
+
+static inline int clz(unsigned int mask) {
+ mask >>= 1;
+ mask |= mask >> 1;
+ mask |= mask >> 2;
+ mask |= mask >> 4;
+ mask |= mask >> 8;
+ mask |= mask >> 16;
+ mask++;
+ return 32 - ffs(mask);
+}
+
+static inline int clzll(unsigned long long mask) {
+ if (mask >> 32)
+ return clz((unsigned)(mask >> 32));
+ else
+ return clz((unsigned)mask) + 32;
+}
+#endif /* !_MSC_VER && !__GNUC__ */
#ifndef static_assert
#define CHECK_OFFSET(type, field, name) \
--
2.32.0
|