summaryrefslogtreecommitdiffstats
path: root/sys/ia64/include
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>2003-12-10 22:47:02 +0000
committerpeter <peter@FreeBSD.org>2003-12-10 22:47:02 +0000
commitf5f05f9b78d6d0ea52e30806d93346aa7244c229 (patch)
tree2ca0944a98cc390325c156441bfec46e6ac9cd5c /sys/ia64/include
parenta767a6c3925577956c9bcd5b8aff408bb03f50a8 (diff)
downloadFreeBSD-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.h23
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
OpenPOWER on IntegriCloud