diff options
Diffstat (limited to 'include/asm-x86/bitops.h')
| -rw-r--r-- | include/asm-x86/bitops.h | 99 |
1 files changed, 98 insertions, 1 deletions
diff --git a/include/asm-x86/bitops.h b/include/asm-x86/bitops.h index 1ae7b270a1ef..1b6f547cb6bd 100644 --- a/include/asm-x86/bitops.h +++ b/include/asm-x86/bitops.h | |||
| @@ -67,7 +67,6 @@ static inline void __set_bit(int nr, volatile void *addr) | |||
| 67 | : "Ir" (nr) : "memory"); | 67 | : "Ir" (nr) : "memory"); |
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | |||
| 71 | /** | 70 | /** |
| 72 | * clear_bit - Clears a bit in memory | 71 | * clear_bit - Clears a bit in memory |
| 73 | * @nr: Bit to clear | 72 | * @nr: Bit to clear |
| @@ -304,6 +303,104 @@ static int test_bit(int nr, const volatile unsigned long *addr); | |||
| 304 | 303 | ||
| 305 | #undef BASE_ADDR | 304 | #undef BASE_ADDR |
| 306 | #undef BIT_ADDR | 305 | #undef BIT_ADDR |
| 306 | /** | ||
| 307 | * __ffs - find first set bit in word | ||
| 308 | * @word: The word to search | ||
| 309 | * | ||
| 310 | * Undefined if no bit exists, so code should check against 0 first. | ||
| 311 | */ | ||
| 312 | static inline unsigned long __ffs(unsigned long word) | ||
| 313 | { | ||
| 314 | __asm__("bsf %1,%0" | ||
| 315 | :"=r" (word) | ||
| 316 | :"rm" (word)); | ||
| 317 | return word; | ||
| 318 | } | ||
| 319 | |||
| 320 | /** | ||
| 321 | * ffz - find first zero bit in word | ||
| 322 | * @word: The word to search | ||
| 323 | * | ||
| 324 | * Undefined if no zero exists, so code should check against ~0UL first. | ||
| 325 | */ | ||
| 326 | static inline unsigned long ffz(unsigned long word) | ||
| 327 | { | ||
| 328 | __asm__("bsf %1,%0" | ||
| 329 | :"=r" (word) | ||
| 330 | :"r" (~word)); | ||
| 331 | return word; | ||
| 332 | } | ||
| 333 | |||
| 334 | /* | ||
| 335 | * __fls: find last set bit in word | ||
| 336 | * @word: The word to search | ||
| 337 | * | ||
| 338 | * Undefined if no zero exists, so code should check against ~0UL first. | ||
| 339 | */ | ||
| 340 | static inline unsigned long __fls(unsigned long word) | ||
| 341 | { | ||
| 342 | __asm__("bsr %1,%0" | ||
| 343 | :"=r" (word) | ||
| 344 | :"rm" (word)); | ||
| 345 | return word; | ||
| 346 | } | ||
| 347 | |||
| 348 | #ifdef __KERNEL__ | ||
| 349 | /** | ||
| 350 | * ffs - find first set bit in word | ||
| 351 | * @x: the word to search | ||
| 352 | * | ||
| 353 | * This is defined the same way as the libc and compiler builtin ffs | ||
| 354 | * routines, therefore differs in spirit from the other bitops. | ||
| 355 | * | ||
| 356 | * ffs(value) returns 0 if value is 0 or the position of the first | ||
| 357 | * set bit if value is nonzero. The first (least significant) bit | ||
| 358 | * is at position 1. | ||
| 359 | */ | ||
| 360 | static inline int ffs(int x) | ||
| 361 | { | ||
| 362 | int r; | ||
| 363 | #ifdef CONFIG_X86_CMOV | ||
| 364 | __asm__("bsfl %1,%0\n\t" | ||
| 365 | "cmovzl %2,%0" | ||
| 366 | : "=r" (r) : "rm" (x), "r" (-1)); | ||
| 367 | #else | ||
| 368 | __asm__("bsfl %1,%0\n\t" | ||
| 369 | "jnz 1f\n\t" | ||
| 370 | "movl $-1,%0\n" | ||
| 371 | "1:" : "=r" (r) : "rm" (x)); | ||
| 372 | #endif | ||
| 373 | return r + 1; | ||
| 374 | } | ||
| 375 | |||
| 376 | /** | ||
| 377 | * fls - find last set bit in word | ||
| 378 | * @x: the word to search | ||
| 379 | * | ||
| 380 | * This is defined in a similar way as the libc and compiler builtin | ||
| 381 | * ffs, but returns the position of the most significant set bit. | ||
| 382 | * | ||
| 383 | * fls(value) returns 0 if value is 0 or the position of the last | ||
| 384 | * set bit if value is nonzero. The last (most significant) bit is | ||
| 385 | * at position 32. | ||
| 386 | */ | ||
| 387 | static inline int fls(int x) | ||
| 388 | { | ||
| 389 | int r; | ||
| 390 | #ifdef CONFIG_X86_CMOV | ||
| 391 | __asm__("bsrl %1,%0\n\t" | ||
| 392 | "cmovzl %2,%0" | ||
| 393 | : "=&r" (r) : "rm" (x), "rm" (-1)); | ||
| 394 | #else | ||
| 395 | __asm__("bsrl %1,%0\n\t" | ||
| 396 | "jnz 1f\n\t" | ||
| 397 | "movl $-1,%0\n" | ||
| 398 | "1:" : "=r" (r) : "rm" (x)); | ||
| 399 | #endif | ||
| 400 | return r + 1; | ||
| 401 | } | ||
| 402 | #endif /* __KERNEL__ */ | ||
| 403 | |||
| 307 | #undef ADDR | 404 | #undef ADDR |
| 308 | 405 | ||
| 309 | #ifdef CONFIG_X86_32 | 406 | #ifdef CONFIG_X86_32 |
