aboutsummaryrefslogtreecommitdiffstats
path: root/cheesemap.c
diff options
context:
space:
mode:
authorFabrice <fabrice@schaub-dev.xyz>2026-03-23 07:52:39 +0100
committerFabrice <fabrice@schaub-dev.xyz>2026-03-23 07:52:39 +0100
commit17f1bd79e251bd570ad79da2249f8e0bdaf5aa9f (patch)
tree192f949e141321a38df695b7d5b15ea95a206a4e /cheesemap.c
parent567fa14e1ea5641cfabcc91d426a16088154c5ba (diff)
specialize for 8 byte and 16 byte groups
Diffstat (limited to 'cheesemap.c')
-rw-r--r--cheesemap.c42
1 files changed, 27 insertions, 15 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