diff options
author | peter <peter@FreeBSD.org> | 2003-12-10 22:47:02 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 2003-12-10 22:47:02 +0000 |
commit | f5f05f9b78d6d0ea52e30806d93346aa7244c229 (patch) | |
tree | 2ca0944a98cc390325c156441bfec46e6ac9cd5c /sys/ia64/include | |
parent | a767a6c3925577956c9bcd5b8aff408bb03f50a8 (diff) | |
download | FreeBSD-src-f5f05f9b78d6d0ea52e30806d93346aa7244c229.zip FreeBSD-src-f5f05f9b78d6d0ea52e30806d93346aa7244c229.tar.gz |
Use ffs(x) == popcnt(x ^ (x - 1)) to implement 64 bit ffsl(). gcc's
ffs() builtin uses this already but truncates the upper 32 bits.
Diffstat (limited to 'sys/ia64/include')
-rw-r--r-- | sys/ia64/include/runq.h | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/sys/ia64/include/runq.h b/sys/ia64/include/runq.h index 9f844b6..2a8eb7f 100644 --- a/sys/ia64/include/runq.h +++ b/sys/ia64/include/runq.h @@ -36,23 +36,30 @@ #define RQB_BIT(pri) (1UL << ((pri) & (RQB_BPW - 1))) #define RQB_WORD(pri) ((pri) >> RQB_L2BPW) -#define RQB_FFS(word) (ffs64(word) - 1) +#define RQB_FFS(word) (__ffsl(word) - 1) /* * Type of run queue status word. */ typedef u_int64_t rqb_word_t; -static __inline u_long -ffs64(u_long mask) +static __inline u_int64_t +__popcnt(u_int64_t bits) { - u_long bit; + u_int64_t result; - if (mask == 0) + __asm __volatile("popcnt %0=%1" : "=r" (result) : "r" (bits)); + return result; +} + + +static __inline int +__ffsl(u_long mask) +{ + + if (__predict_false(mask == 0ul)) return (0); - for (bit = 1; (mask & 1UL) == 0; bit++) - mask >>= 1UL; - return (bit); + return (popcnt(mask ^ (mask - 1))); } #endif |