summaryrefslogtreecommitdiffstats
path: root/sys/amd64/include/cpufunc.h
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>2003-12-06 23:22:43 +0000
committerpeter <peter@FreeBSD.org>2003-12-06 23:22:43 +0000
commit955dcc87c12e5c1e8d571b6776bd8b2d326d650b (patch)
treea1d337c5f6340fffd5e1a12a2a93b3a37d233e7c /sys/amd64/include/cpufunc.h
parente875083eeafdcb1031b930a65960415347bf6127 (diff)
downloadFreeBSD-src-955dcc87c12e5c1e8d571b6776bd8b2d326d650b.zip
FreeBSD-src-955dcc87c12e5c1e8d571b6776bd8b2d326d650b.tar.gz
Add 64 bit bsf*/ffs* routines. Have the ffs() inline use gcc's builtin
because it uses the better cmove instructions to avoid branches.
Diffstat (limited to 'sys/amd64/include/cpufunc.h')
-rw-r--r--sys/amd64/include/cpufunc.h41
1 files changed, 40 insertions, 1 deletions
diff --git a/sys/amd64/include/cpufunc.h b/sys/amd64/include/cpufunc.h
index f060785..c024c1d 100644
--- a/sys/amd64/include/cpufunc.h
+++ b/sys/amd64/include/cpufunc.h
@@ -77,6 +77,15 @@ bsfl(u_int mask)
return (result);
}
+static __inline u_long
+bsfq(u_long mask)
+{
+ u_long result;
+
+ __asm __volatile("bsfq %1,%0" : "=r" (result) : "rm" (mask));
+ return (result);
+}
+
static __inline u_int
bsrl(u_int mask)
{
@@ -86,6 +95,15 @@ bsrl(u_int mask)
return (result);
}
+static __inline u_long
+bsrq(u_long mask)
+{
+ u_long result;
+
+ __asm __volatile("bsrq %1,%0" : "=r" (result) : "rm" (mask));
+ return (result);
+}
+
static __inline void
disable_intr(void)
{
@@ -111,13 +129,26 @@ enable_intr(void)
static __inline int
ffs(int mask)
{
+#if 0
/*
* Note that gcc-2's builtin ffs would be used if we didn't declare
* this inline or turn off the builtin. The builtin is faster but
* broken in gcc-2.4.5 and slower but working in gcc-2.5 and later
* versions.
*/
- return (mask == 0 ? mask : (int)bsfl((u_int)mask) + 1);
+ return (mask == 0 ? mask : (int)bsfl((u_int)mask) + 1);
+#else
+ /* Actually, the above is way out of date. The builtins use cmov etc */
+ return (__builtin_ffs(mask));
+#endif
+}
+
+#define HAVE_INLINE_FFSL
+
+static __inline int
+ffsl(long mask)
+{
+ return (mask == 0 ? mask : (int)bsfq((u_long)mask) + 1);
}
#define HAVE_INLINE_FLS
@@ -128,6 +159,14 @@ fls(int mask)
return (mask == 0 ? mask : (int)bsrl((u_int)mask) + 1);
}
+#define HAVE_INLINE_FLSL
+
+static __inline int
+flsl(long mask)
+{
+ return (mask == 0 ? mask : (int)bsrq((u_long)mask) + 1);
+}
+
static __inline void
halt(void)
{
OpenPOWER on IntegriCloud