diff options
author | peter <peter@FreeBSD.org> | 2003-12-06 23:22:43 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 2003-12-06 23:22:43 +0000 |
commit | 955dcc87c12e5c1e8d571b6776bd8b2d326d650b (patch) | |
tree | a1d337c5f6340fffd5e1a12a2a93b3a37d233e7c /sys/amd64/include/cpufunc.h | |
parent | e875083eeafdcb1031b930a65960415347bf6127 (diff) | |
download | FreeBSD-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.h | 41 |
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) { |