diff options
author | Nicolas Pitre <nico@cam.org> | 2008-12-04 03:59:41 +0100 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2008-12-04 09:21:55 +0000 |
commit | 94fc7336646b392234c0fafea5d696d020c3677c (patch) | |
tree | 95137c3233bf0d4f07a52e8529122dfa284a5353 | |
parent | 82676d76252680fc035247fd4cfdb07ffce5db52 (diff) | |
download | linux-stable-94fc7336646b392234c0fafea5d696d020c3677c.tar.gz linux-stable-94fc7336646b392234c0fafea5d696d020c3677c.tar.bz2 linux-stable-94fc7336646b392234c0fafea5d696d020c3677c.zip |
[ARM] 5339/1: fix __fls() on ARM
Commit 0c65f459ce6c intended to fix truncation issues with fls() on
ARMv5+ by renaming it to __fls() and wrapping it into a C function.
However that didn't take into account the fact that __fls() already
already had different semantics in the kernel.
Let's move the __fls() code into fls() function directly, and redefine
__fls() with the appropriate semantics. While at it, bring a generic
__fls() definition for pre ARMv5 too.
Signed-off-by: Nicolas Pitre <nico@marvell.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r-- | arch/arm/include/asm/bitops.h | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/arch/arm/include/asm/bitops.h b/arch/arm/include/asm/bitops.h index 9a1db20e032a..63a481fbbed4 100644 --- a/arch/arm/include/asm/bitops.h +++ b/arch/arm/include/asm/bitops.h @@ -237,6 +237,7 @@ extern int _find_next_bit_be(const unsigned long *p, int size, int offset); #if __LINUX_ARM_ARCH__ < 5 #include <asm-generic/bitops/ffz.h> +#include <asm-generic/bitops/__fls.h> #include <asm-generic/bitops/__ffs.h> #include <asm-generic/bitops/fls.h> #include <asm-generic/bitops/ffs.h> @@ -277,16 +278,19 @@ static inline int constant_fls(int x) * the clz instruction for much better code efficiency. */ -#define __fls(x) \ - ( __builtin_constant_p(x) ? constant_fls(x) : \ - ({ int __r; asm("clz\t%0, %1" : "=r"(__r) : "r"(x) : "cc"); 32-__r; }) ) - -/* Implement fls() in C so that 64-bit args are suitably truncated */ static inline int fls(int x) { - return __fls(x); + int ret; + + if (__builtin_constant_p(x)) + return constant_fls(x); + + asm("clz\t%0, %1" : "=r" (ret) : "r" (x) : "cc"); + ret = 32 - ret; + return ret; } +#define __fls(x) (fls(x) - 1) #define ffs(x) ({ unsigned long __t = (x); fls(__t & -__t); }) #define __ffs(x) (ffs(x) - 1) #define ffz(x) __ffs( ~(x) ) |