Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] FRV: Optimise ffs()

Optimise ffs(x) by using fls(x & x - 1) which we optimise to use the SCAN
instruction.

Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

David Howells and committed by
Linus Torvalds
cf134483 a8ad27d0

+31 -2
+31 -2
include/asm-frv/bitops.h
··· 157 157 __constant_test_bit((nr),(addr)) : \ 158 158 __test_bit((nr),(addr))) 159 159 160 - #include <asm-generic/bitops/ffs.h> 161 - #include <asm-generic/bitops/__ffs.h> 162 160 #include <asm-generic/bitops/find.h> 163 161 164 162 /** ··· 223 225 ); 224 226 return bit; 225 227 228 + } 229 + 230 + /** 231 + * ffs - find first bit set 232 + * @x: the word to search 233 + * 234 + * - return 32..1 to indicate bit 31..0 most least significant bit set 235 + * - return 0 to indicate no bits set 236 + */ 237 + static inline __attribute__((const)) 238 + int ffs(int x) 239 + { 240 + /* Note: (x & -x) gives us a mask that is the least significant 241 + * (rightmost) 1-bit of the value in x. 242 + */ 243 + return fls(x & -x); 244 + } 245 + 246 + /** 247 + * __ffs - find first bit set 248 + * @x: the word to search 249 + * 250 + * - return 31..0 to indicate bit 31..0 most least significant bit set 251 + * - if no bits are set in x, the result is undefined 252 + */ 253 + static inline __attribute__((const)) 254 + int __ffs(unsigned long x) 255 + { 256 + int bit; 257 + asm("scan %1,gr0,%0" : "=r"(bit) : "r"(x & -x)); 258 + return 31 - bit; 226 259 } 227 260 228 261 #include <asm-generic/bitops/sched.h>