aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cheesemap.c42
-rw-r--r--cheesemap.h5
2 files changed, 28 insertions, 19 deletions
diff --git a/cheesemap.c b/cheesemap.c
index 4e56823..ade0659 100644
--- a/cheesemap.c
+++ b/cheesemap.c
@@ -6,9 +6,10 @@
#include <stdlib.h>
#include <string.h>
-static inline uintptr_t cm_ctz(uintptr_t val) {
+#define CM_ATTR(...) __attribute__((__VA_ARGS__))
+
+CM_ATTR(hot) static inline uintptr_t cm_ctz(uintptr_t val) {
assert(val != 0);
-#if defined(__GNUC__) || defined(__clang__)
#if UINTPTR_MAX == UINT64_MAX
return (uintptr_t)__builtin_ctzll(val);
#elif UINTPTR_MAX == UINT32_MAX
@@ -16,14 +17,10 @@ static inline uintptr_t cm_ctz(uintptr_t val) {
#else
#error "unknown word width"
#endif
-#else
-#error "ctz not implemented"
-#endif
}
-static inline uintptr_t cm_clz(uintptr_t val) {
+CM_ATTR(hot) static inline uintptr_t cm_clz(uintptr_t val) {
assert(val != 0);
-#if defined(__GNUC__) || defined(__clang__)
#if UINTPTR_MAX == UINT64_MAX
return (uintptr_t)__builtin_clzll(val);
#elif UINTPTR_MAX == UINT32_MAX
@@ -31,23 +28,38 @@ static inline uintptr_t cm_clz(uintptr_t val) {
#else
#error "unknown word width"
#endif
-#else
-#error "clz not implemented"
-#endif
}
-static inline uintptr_t cm_bitmask_lowest_set_bit(bitmask_t mask) {
+CM_ATTR(hot) static inline uintptr_t cm_bitmask_lowest_set_bit(bitmask_t mask) {
+#if CM_GROUP_SIZE == 8
return cm_ctz(mask) / CHAR_BIT;
+#elif CM_GROUP_SIZE == 16
+ return cm_ctz(mask)
+#else
+#error "unknown group size"
+#endif
}
-static inline uintptr_t cm_bitmask_ctz(bitmask_t mask) {
- if (mask == 0) return sizeof(mask) * CHAR_BIT / CHAR_BIT;
+CM_ATTR(hot) static inline uintptr_t cm_bitmask_ctz(bitmask_t mask) {
+ if (mask == 0) return CM_GROUP_SIZE;
+#if CM_GROUP_SIZE == 8
return cm_ctz(mask) / CHAR_BIT;
+#elif CM_GROUP_SIZE == 16
+ return cm_ctz(mask);
+#else
+#error "unknown group size"
+#endif
}
-static inline uintptr_t cm_bitmask_clz(bitmask_t mask) {
- if (mask == 0) return sizeof(mask) * CHAR_BIT / CHAR_BIT;
+CM_ATTR(hot) static inline uintptr_t cm_bitmask_clz(bitmask_t mask) {
+ if (mask == 0) return CM_GROUP_SIZE;
+#if CM_GROUP_SIZE == 8
return cm_clz(mask) / CHAR_BIT;
+#elif CM_GROUP_SIZE == 16
+ return cm_clz(mask);
+#else
+#error "unknown group size"
+#endif
}
#define cm_max(x, y) x > y ? x : y
diff --git a/cheesemap.h b/cheesemap.h
index 50fa7bf..7cdb2de 100644
--- a/cheesemap.h
+++ b/cheesemap.h
@@ -20,10 +20,7 @@ extern "C" {
typedef uintptr_t group_t;
typedef group_t bitmask_t;
-
-enum {
- CM_GROUP_SIZE = sizeof(group_t),
-};
+#define CM_GROUP_SIZE __SIZEOF_POINTER__
////////////////////////////////
// cheesemap callback functions