From ef6051a90e2ad1af636e99d1d4603fdcf2adfcbe Mon Sep 17 00:00:00 2001 From: Chris Zankel Date: Thu, 31 May 2007 17:41:14 -0700 Subject: [PATCH] [XTENSA] fix bit operations in bitops.h A macro used internally in the bitops.h file to identify the number of leading zeros (__cntlz) was implemented incorrectly for Xtensa processors that don't provide the 'nsa/nsau' instructions. As a result, the dependent functions and macros (ffs, ffz, fls) were broken. Signed-off-by: Chris Zankel --- include/asm-xtensa/bitops.h | 60 ++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 34 deletions(-) diff --git a/include/asm-xtensa/bitops.h b/include/asm-xtensa/bitops.h index d815649617aa..96303dff3ee4 100644 --- a/include/asm-xtensa/bitops.h +++ b/include/asm-xtensa/bitops.h @@ -7,7 +7,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2001 - 2005 Tensilica Inc. + * Copyright (C) 2001 - 2007 Tensilica Inc. */ #ifndef _XTENSA_BITOPS_H @@ -31,64 +31,44 @@ #if XCHAL_HAVE_NSA -static __inline__ int __cntlz (unsigned long x) +static inline unsigned long __cntlz (unsigned long x) { int lz; asm ("nsau %0, %1" : "=r" (lz) : "r" (x)); - return 31 - lz; + return lz; } -#else - -static __inline__ int __cntlz (unsigned long x) -{ - unsigned long sum, x1, x2, x4, x8, x16; - x1 = x & 0xAAAAAAAA; - x2 = x & 0xCCCCCCCC; - x4 = x & 0xF0F0F0F0; - x8 = x & 0xFF00FF00; - x16 = x & 0xFFFF0000; - sum = x2 ? 2 : 0; - sum += (x16 != 0) * 16; - sum += (x8 != 0) * 8; - sum += (x4 != 0) * 4; - sum += (x1 != 0); - - return sum; -} - -#endif - /* * ffz: Find first zero in word. Undefined if no zero exists. * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1). */ -static __inline__ int ffz(unsigned long x) +static inline int ffz(unsigned long x) { - if ((x = ~x) == 0) - return 32; - return __cntlz(x & -x); + return 31 - __cntlz(~x & -~x); } /* * __ffs: Find first bit set in word. Return 0 for bit 0 */ -static __inline__ int __ffs(unsigned long x) +static inline int __ffs(unsigned long x) { - return __cntlz(x & -x); + return 31 - __cntlz(x & -x); } + +#ifdef __KERNEL__ + /* * ffs: Find first bit set in word. This is defined the same way as * the libc and compiler builtin ffs routines, therefore * differs in spirit from the above ffz (man ffs). */ -static __inline__ int ffs(unsigned long x) +static inline int ffs(unsigned long x) { - return __cntlz(x & -x) + 1; + return 32 - __cntlz(x & -x); } /* @@ -96,10 +76,22 @@ static __inline__ int ffs(unsigned long x) * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32. */ -static __inline__ int fls (unsigned int x) +static inline int fls (unsigned int x) { - return __cntlz(x); + return 32 - __cntlz(x); } + +#else + +/* Use the generic implementation if we don't have the nsa/nsau instructions. */ + +# include +# include +# include +# include + +#endif + #include #include #include