Skip to content

Commit 340d093

Browse files
committed
Add rv_ctz() for efficient count trailing zero operations
Introduce the rv_ctz() function to compute the count of trailing zeros in a 32-bit integer. This function serves as a prerequisite for implementing the ctz instruction in the RISC-V Zbb extension.
1 parent 5b90d0f commit 340d093

File tree

1 file changed

+37
-0
lines changed

1 file changed

+37
-0
lines changed

src/common.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,43 @@ static inline int rv_clz(uint32_t v)
7272
}
7373
#endif
7474

75+
#if defined(_MSC_VER)
76+
#include <intrin.h>
77+
static inline int rv_ctz(uint32_t v)
78+
{
79+
/* 0 is considered as undefined behavior */
80+
assert(v);
81+
82+
uint32_t trailing_zero = 0;
83+
_BitScanForward(&trailing_zero, v);
84+
return trailing_zero;
85+
}
86+
#elif defined(__GNUC__) || defined(__clang__)
87+
static inline int rv_ctz(uint32_t v)
88+
{
89+
/* https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html */
90+
/* 0 is considered as undefined behavior */
91+
assert(v);
92+
93+
return __builtin_ctz(v);
94+
}
95+
#else /* generic implementation */
96+
static inline int rv_ctz(uint32_t v)
97+
{
98+
/* 0 is considered as undefined behavior */
99+
assert(v);
100+
101+
/* https://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightMultLookup
102+
*/
103+
104+
static const int mul_debruijn[32] = {
105+
0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
106+
31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9};
107+
108+
return mul_debruijn[((uint32_t) ((v & -v) * 0x077CB531U)) >> 27];
109+
}
110+
#endif
111+
75112
/*
76113
* Integer log base 2
77114
*

0 commit comments

Comments
 (0)