diff options
| -rw-r--r-- | include/asm-arm/bitops.h | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/include/asm-arm/bitops.h b/include/asm-arm/bitops.h index d02de721ecc1..eaecd553e856 100644 --- a/include/asm-arm/bitops.h +++ b/include/asm-arm/bitops.h | |||
| @@ -344,13 +344,42 @@ static inline unsigned long __ffs(unsigned long word) | |||
| 344 | 344 | ||
| 345 | #else | 345 | #else |
| 346 | 346 | ||
| 347 | static inline int constant_fls(int x) | ||
| 348 | { | ||
| 349 | int r = 32; | ||
| 350 | |||
| 351 | if (!x) | ||
| 352 | return 0; | ||
| 353 | if (!(x & 0xffff0000u)) { | ||
| 354 | x <<= 16; | ||
| 355 | r -= 16; | ||
| 356 | } | ||
| 357 | if (!(x & 0xff000000u)) { | ||
| 358 | x <<= 8; | ||
| 359 | r -= 8; | ||
| 360 | } | ||
| 361 | if (!(x & 0xf0000000u)) { | ||
| 362 | x <<= 4; | ||
| 363 | r -= 4; | ||
| 364 | } | ||
| 365 | if (!(x & 0xc0000000u)) { | ||
| 366 | x <<= 2; | ||
| 367 | r -= 2; | ||
| 368 | } | ||
| 369 | if (!(x & 0x80000000u)) { | ||
| 370 | x <<= 1; | ||
| 371 | r -= 1; | ||
| 372 | } | ||
| 373 | return r; | ||
| 374 | } | ||
| 375 | |||
| 347 | /* | 376 | /* |
| 348 | * On ARMv5 and above those functions can be implemented around | 377 | * On ARMv5 and above those functions can be implemented around |
| 349 | * the clz instruction for much better code efficiency. | 378 | * the clz instruction for much better code efficiency. |
| 350 | */ | 379 | */ |
| 351 | 380 | ||
| 352 | #define fls(x) \ | 381 | #define fls(x) \ |
| 353 | ( __builtin_constant_p(x) ? generic_fls(x) : \ | 382 | ( __builtin_constant_p(x) ? constant_fls(x) : \ |
| 354 | ({ int __r; asm("clz\t%0, %1" : "=r"(__r) : "r"(x) : "cc"); 32-__r; }) ) | 383 | ({ int __r; asm("clz\t%0, %1" : "=r"(__r) : "r"(x) : "cc"); 32-__r; }) ) |
| 355 | #define fls64(x) generic_fls64(x) | 384 | #define fls64(x) generic_fls64(x) |
| 356 | #define ffs(x) ({ unsigned long __t = (x); fls(__t & -__t); }) | 385 | #define ffs(x) ({ unsigned long __t = (x); fls(__t & -__t); }) |
