diff options
Diffstat (limited to 'include/asm-mips/bitops.h')
-rw-r--r-- | include/asm-mips/bitops.h | 209 |
1 files changed, 163 insertions, 46 deletions
diff --git a/include/asm-mips/bitops.h b/include/asm-mips/bitops.h index eb8d79dba11c..5496f9064a6a 100644 --- a/include/asm-mips/bitops.h +++ b/include/asm-mips/bitops.h | |||
@@ -12,20 +12,21 @@ | |||
12 | #include <linux/config.h> | 12 | #include <linux/config.h> |
13 | #include <linux/compiler.h> | 13 | #include <linux/compiler.h> |
14 | #include <linux/types.h> | 14 | #include <linux/types.h> |
15 | #include <asm/bug.h> | ||
15 | #include <asm/byteorder.h> /* sigh ... */ | 16 | #include <asm/byteorder.h> /* sigh ... */ |
16 | #include <asm/cpu-features.h> | 17 | #include <asm/cpu-features.h> |
17 | 18 | ||
18 | #if (_MIPS_SZLONG == 32) | 19 | #if (_MIPS_SZLONG == 32) |
19 | #define SZLONG_LOG 5 | 20 | #define SZLONG_LOG 5 |
20 | #define SZLONG_MASK 31UL | 21 | #define SZLONG_MASK 31UL |
21 | #define __LL "ll " | 22 | #define __LL "ll " |
22 | #define __SC "sc " | 23 | #define __SC "sc " |
23 | #define cpu_to_lelongp(x) cpu_to_le32p((__u32 *) (x)) | 24 | #define cpu_to_lelongp(x) cpu_to_le32p((__u32 *) (x)) |
24 | #elif (_MIPS_SZLONG == 64) | 25 | #elif (_MIPS_SZLONG == 64) |
25 | #define SZLONG_LOG 6 | 26 | #define SZLONG_LOG 6 |
26 | #define SZLONG_MASK 63UL | 27 | #define SZLONG_MASK 63UL |
27 | #define __LL "lld " | 28 | #define __LL "lld " |
28 | #define __SC "scd " | 29 | #define __SC "scd " |
29 | #define cpu_to_lelongp(x) cpu_to_le64p((__u64 *) (x)) | 30 | #define cpu_to_lelongp(x) cpu_to_le64p((__u64 *) (x)) |
30 | #endif | 31 | #endif |
31 | 32 | ||
@@ -72,18 +73,22 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) | |||
72 | 73 | ||
73 | if (cpu_has_llsc && R10000_LLSC_WAR) { | 74 | if (cpu_has_llsc && R10000_LLSC_WAR) { |
74 | __asm__ __volatile__( | 75 | __asm__ __volatile__( |
76 | " .set mips3 \n" | ||
75 | "1: " __LL "%0, %1 # set_bit \n" | 77 | "1: " __LL "%0, %1 # set_bit \n" |
76 | " or %0, %2 \n" | 78 | " or %0, %2 \n" |
77 | " "__SC "%0, %1 \n" | 79 | " " __SC "%0, %1 \n" |
78 | " beqzl %0, 1b \n" | 80 | " beqzl %0, 1b \n" |
81 | " .set mips0 \n" | ||
79 | : "=&r" (temp), "=m" (*m) | 82 | : "=&r" (temp), "=m" (*m) |
80 | : "ir" (1UL << (nr & SZLONG_MASK)), "m" (*m)); | 83 | : "ir" (1UL << (nr & SZLONG_MASK)), "m" (*m)); |
81 | } else if (cpu_has_llsc) { | 84 | } else if (cpu_has_llsc) { |
82 | __asm__ __volatile__( | 85 | __asm__ __volatile__( |
86 | " .set mips3 \n" | ||
83 | "1: " __LL "%0, %1 # set_bit \n" | 87 | "1: " __LL "%0, %1 # set_bit \n" |
84 | " or %0, %2 \n" | 88 | " or %0, %2 \n" |
85 | " "__SC "%0, %1 \n" | 89 | " " __SC "%0, %1 \n" |
86 | " beqz %0, 1b \n" | 90 | " beqz %0, 1b \n" |
91 | " .set mips0 \n" | ||
87 | : "=&r" (temp), "=m" (*m) | 92 | : "=&r" (temp), "=m" (*m) |
88 | : "ir" (1UL << (nr & SZLONG_MASK)), "m" (*m)); | 93 | : "ir" (1UL << (nr & SZLONG_MASK)), "m" (*m)); |
89 | } else { | 94 | } else { |
@@ -132,18 +137,22 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr) | |||
132 | 137 | ||
133 | if (cpu_has_llsc && R10000_LLSC_WAR) { | 138 | if (cpu_has_llsc && R10000_LLSC_WAR) { |
134 | __asm__ __volatile__( | 139 | __asm__ __volatile__( |
140 | " .set mips3 \n" | ||
135 | "1: " __LL "%0, %1 # clear_bit \n" | 141 | "1: " __LL "%0, %1 # clear_bit \n" |
136 | " and %0, %2 \n" | 142 | " and %0, %2 \n" |
137 | " " __SC "%0, %1 \n" | 143 | " " __SC "%0, %1 \n" |
138 | " beqzl %0, 1b \n" | 144 | " beqzl %0, 1b \n" |
145 | " .set mips0 \n" | ||
139 | : "=&r" (temp), "=m" (*m) | 146 | : "=&r" (temp), "=m" (*m) |
140 | : "ir" (~(1UL << (nr & SZLONG_MASK))), "m" (*m)); | 147 | : "ir" (~(1UL << (nr & SZLONG_MASK))), "m" (*m)); |
141 | } else if (cpu_has_llsc) { | 148 | } else if (cpu_has_llsc) { |
142 | __asm__ __volatile__( | 149 | __asm__ __volatile__( |
150 | " .set mips3 \n" | ||
143 | "1: " __LL "%0, %1 # clear_bit \n" | 151 | "1: " __LL "%0, %1 # clear_bit \n" |
144 | " and %0, %2 \n" | 152 | " and %0, %2 \n" |
145 | " " __SC "%0, %1 \n" | 153 | " " __SC "%0, %1 \n" |
146 | " beqz %0, 1b \n" | 154 | " beqz %0, 1b \n" |
155 | " .set mips0 \n" | ||
147 | : "=&r" (temp), "=m" (*m) | 156 | : "=&r" (temp), "=m" (*m) |
148 | : "ir" (~(1UL << (nr & SZLONG_MASK))), "m" (*m)); | 157 | : "ir" (~(1UL << (nr & SZLONG_MASK))), "m" (*m)); |
149 | } else { | 158 | } else { |
@@ -191,10 +200,12 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr) | |||
191 | unsigned long temp; | 200 | unsigned long temp; |
192 | 201 | ||
193 | __asm__ __volatile__( | 202 | __asm__ __volatile__( |
203 | " .set mips3 \n" | ||
194 | "1: " __LL "%0, %1 # change_bit \n" | 204 | "1: " __LL "%0, %1 # change_bit \n" |
195 | " xor %0, %2 \n" | 205 | " xor %0, %2 \n" |
196 | " "__SC "%0, %1 \n" | 206 | " " __SC "%0, %1 \n" |
197 | " beqzl %0, 1b \n" | 207 | " beqzl %0, 1b \n" |
208 | " .set mips0 \n" | ||
198 | : "=&r" (temp), "=m" (*m) | 209 | : "=&r" (temp), "=m" (*m) |
199 | : "ir" (1UL << (nr & SZLONG_MASK)), "m" (*m)); | 210 | : "ir" (1UL << (nr & SZLONG_MASK)), "m" (*m)); |
200 | } else if (cpu_has_llsc) { | 211 | } else if (cpu_has_llsc) { |
@@ -202,10 +213,12 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr) | |||
202 | unsigned long temp; | 213 | unsigned long temp; |
203 | 214 | ||
204 | __asm__ __volatile__( | 215 | __asm__ __volatile__( |
216 | " .set mips3 \n" | ||
205 | "1: " __LL "%0, %1 # change_bit \n" | 217 | "1: " __LL "%0, %1 # change_bit \n" |
206 | " xor %0, %2 \n" | 218 | " xor %0, %2 \n" |
207 | " "__SC "%0, %1 \n" | 219 | " " __SC "%0, %1 \n" |
208 | " beqz %0, 1b \n" | 220 | " beqz %0, 1b \n" |
221 | " .set mips0 \n" | ||
209 | : "=&r" (temp), "=m" (*m) | 222 | : "=&r" (temp), "=m" (*m) |
210 | : "ir" (1UL << (nr & SZLONG_MASK)), "m" (*m)); | 223 | : "ir" (1UL << (nr & SZLONG_MASK)), "m" (*m)); |
211 | } else { | 224 | } else { |
@@ -253,14 +266,16 @@ static inline int test_and_set_bit(unsigned long nr, | |||
253 | unsigned long temp, res; | 266 | unsigned long temp, res; |
254 | 267 | ||
255 | __asm__ __volatile__( | 268 | __asm__ __volatile__( |
269 | " .set mips3 \n" | ||
256 | "1: " __LL "%0, %1 # test_and_set_bit \n" | 270 | "1: " __LL "%0, %1 # test_and_set_bit \n" |
257 | " or %2, %0, %3 \n" | 271 | " or %2, %0, %3 \n" |
258 | " " __SC "%2, %1 \n" | 272 | " " __SC "%2, %1 \n" |
259 | " beqzl %2, 1b \n" | 273 | " beqzl %2, 1b \n" |
260 | " and %2, %0, %3 \n" | 274 | " and %2, %0, %3 \n" |
261 | #ifdef CONFIG_SMP | 275 | #ifdef CONFIG_SMP |
262 | "sync \n" | 276 | " sync \n" |
263 | #endif | 277 | #endif |
278 | " .set mips0 \n" | ||
264 | : "=&r" (temp), "=m" (*m), "=&r" (res) | 279 | : "=&r" (temp), "=m" (*m), "=&r" (res) |
265 | : "r" (1UL << (nr & SZLONG_MASK)), "m" (*m) | 280 | : "r" (1UL << (nr & SZLONG_MASK)), "m" (*m) |
266 | : "memory"); | 281 | : "memory"); |
@@ -271,16 +286,18 @@ static inline int test_and_set_bit(unsigned long nr, | |||
271 | unsigned long temp, res; | 286 | unsigned long temp, res; |
272 | 287 | ||
273 | __asm__ __volatile__( | 288 | __asm__ __volatile__( |
274 | " .set noreorder # test_and_set_bit \n" | 289 | " .set push \n" |
275 | "1: " __LL "%0, %1 \n" | 290 | " .set noreorder \n" |
291 | " .set mips3 \n" | ||
292 | "1: " __LL "%0, %1 # test_and_set_bit \n" | ||
276 | " or %2, %0, %3 \n" | 293 | " or %2, %0, %3 \n" |
277 | " " __SC "%2, %1 \n" | 294 | " " __SC "%2, %1 \n" |
278 | " beqz %2, 1b \n" | 295 | " beqz %2, 1b \n" |
279 | " and %2, %0, %3 \n" | 296 | " and %2, %0, %3 \n" |
280 | #ifdef CONFIG_SMP | 297 | #ifdef CONFIG_SMP |
281 | "sync \n" | 298 | " sync \n" |
282 | #endif | 299 | #endif |
283 | ".set\treorder" | 300 | " .set pop \n" |
284 | : "=&r" (temp), "=m" (*m), "=&r" (res) | 301 | : "=&r" (temp), "=m" (*m), "=&r" (res) |
285 | : "r" (1UL << (nr & SZLONG_MASK)), "m" (*m) | 302 | : "r" (1UL << (nr & SZLONG_MASK)), "m" (*m) |
286 | : "memory"); | 303 | : "memory"); |
@@ -343,15 +360,17 @@ static inline int test_and_clear_bit(unsigned long nr, | |||
343 | unsigned long temp, res; | 360 | unsigned long temp, res; |
344 | 361 | ||
345 | __asm__ __volatile__( | 362 | __asm__ __volatile__( |
363 | " .set mips3 \n" | ||
346 | "1: " __LL "%0, %1 # test_and_clear_bit \n" | 364 | "1: " __LL "%0, %1 # test_and_clear_bit \n" |
347 | " or %2, %0, %3 \n" | 365 | " or %2, %0, %3 \n" |
348 | " xor %2, %3 \n" | 366 | " xor %2, %3 \n" |
349 | __SC "%2, %1 \n" | 367 | " " __SC "%2, %1 \n" |
350 | " beqzl %2, 1b \n" | 368 | " beqzl %2, 1b \n" |
351 | " and %2, %0, %3 \n" | 369 | " and %2, %0, %3 \n" |
352 | #ifdef CONFIG_SMP | 370 | #ifdef CONFIG_SMP |
353 | " sync \n" | 371 | " sync \n" |
354 | #endif | 372 | #endif |
373 | " .set mips0 \n" | ||
355 | : "=&r" (temp), "=m" (*m), "=&r" (res) | 374 | : "=&r" (temp), "=m" (*m), "=&r" (res) |
356 | : "r" (1UL << (nr & SZLONG_MASK)), "m" (*m) | 375 | : "r" (1UL << (nr & SZLONG_MASK)), "m" (*m) |
357 | : "memory"); | 376 | : "memory"); |
@@ -362,17 +381,19 @@ static inline int test_and_clear_bit(unsigned long nr, | |||
362 | unsigned long temp, res; | 381 | unsigned long temp, res; |
363 | 382 | ||
364 | __asm__ __volatile__( | 383 | __asm__ __volatile__( |
365 | " .set noreorder # test_and_clear_bit \n" | 384 | " .set push \n" |
366 | "1: " __LL "%0, %1 \n" | 385 | " .set noreorder \n" |
386 | " .set mips3 \n" | ||
387 | "1: " __LL "%0, %1 # test_and_clear_bit \n" | ||
367 | " or %2, %0, %3 \n" | 388 | " or %2, %0, %3 \n" |
368 | " xor %2, %3 \n" | 389 | " xor %2, %3 \n" |
369 | __SC "%2, %1 \n" | 390 | " " __SC "%2, %1 \n" |
370 | " beqz %2, 1b \n" | 391 | " beqz %2, 1b \n" |
371 | " and %2, %0, %3 \n" | 392 | " and %2, %0, %3 \n" |
372 | #ifdef CONFIG_SMP | 393 | #ifdef CONFIG_SMP |
373 | " sync \n" | 394 | " sync \n" |
374 | #endif | 395 | #endif |
375 | " .set reorder \n" | 396 | " .set pop \n" |
376 | : "=&r" (temp), "=m" (*m), "=&r" (res) | 397 | : "=&r" (temp), "=m" (*m), "=&r" (res) |
377 | : "r" (1UL << (nr & SZLONG_MASK)), "m" (*m) | 398 | : "r" (1UL << (nr & SZLONG_MASK)), "m" (*m) |
378 | : "memory"); | 399 | : "memory"); |
@@ -435,14 +456,16 @@ static inline int test_and_change_bit(unsigned long nr, | |||
435 | unsigned long temp, res; | 456 | unsigned long temp, res; |
436 | 457 | ||
437 | __asm__ __volatile__( | 458 | __asm__ __volatile__( |
438 | "1: " __LL " %0, %1 # test_and_change_bit \n" | 459 | " .set mips3 \n" |
460 | "1: " __LL "%0, %1 # test_and_change_bit \n" | ||
439 | " xor %2, %0, %3 \n" | 461 | " xor %2, %0, %3 \n" |
440 | " "__SC "%2, %1 \n" | 462 | " " __SC "%2, %1 \n" |
441 | " beqzl %2, 1b \n" | 463 | " beqzl %2, 1b \n" |
442 | " and %2, %0, %3 \n" | 464 | " and %2, %0, %3 \n" |
443 | #ifdef CONFIG_SMP | 465 | #ifdef CONFIG_SMP |
444 | " sync \n" | 466 | " sync \n" |
445 | #endif | 467 | #endif |
468 | " .set mips0 \n" | ||
446 | : "=&r" (temp), "=m" (*m), "=&r" (res) | 469 | : "=&r" (temp), "=m" (*m), "=&r" (res) |
447 | : "r" (1UL << (nr & SZLONG_MASK)), "m" (*m) | 470 | : "r" (1UL << (nr & SZLONG_MASK)), "m" (*m) |
448 | : "memory"); | 471 | : "memory"); |
@@ -453,16 +476,18 @@ static inline int test_and_change_bit(unsigned long nr, | |||
453 | unsigned long temp, res; | 476 | unsigned long temp, res; |
454 | 477 | ||
455 | __asm__ __volatile__( | 478 | __asm__ __volatile__( |
456 | " .set noreorder # test_and_change_bit \n" | 479 | " .set push \n" |
457 | "1: " __LL " %0, %1 \n" | 480 | " .set noreorder \n" |
481 | " .set mips3 \n" | ||
482 | "1: " __LL "%0, %1 # test_and_change_bit \n" | ||
458 | " xor %2, %0, %3 \n" | 483 | " xor %2, %0, %3 \n" |
459 | " "__SC "\t%2, %1 \n" | 484 | " " __SC "\t%2, %1 \n" |
460 | " beqz %2, 1b \n" | 485 | " beqz %2, 1b \n" |
461 | " and %2, %0, %3 \n" | 486 | " and %2, %0, %3 \n" |
462 | #ifdef CONFIG_SMP | 487 | #ifdef CONFIG_SMP |
463 | " sync \n" | 488 | " sync \n" |
464 | #endif | 489 | #endif |
465 | " .set reorder \n" | 490 | " .set pop \n" |
466 | : "=&r" (temp), "=m" (*m), "=&r" (res) | 491 | : "=&r" (temp), "=m" (*m), "=&r" (res) |
467 | : "r" (1UL << (nr & SZLONG_MASK)), "m" (*m) | 492 | : "r" (1UL << (nr & SZLONG_MASK)), "m" (*m) |
468 | : "memory"); | 493 | : "memory"); |
@@ -523,22 +548,60 @@ static inline int test_bit(unsigned long nr, const volatile unsigned long *addr) | |||
523 | } | 548 | } |
524 | 549 | ||
525 | /* | 550 | /* |
526 | * ffz - find first zero in word. | 551 | * Return the bit position (0..63) of the most significant 1 bit in a word |
552 | * Returns -1 if no 1 bit exists | ||
553 | */ | ||
554 | static inline int __ilog2(unsigned long x) | ||
555 | { | ||
556 | int lz; | ||
557 | |||
558 | if (sizeof(x) == 4) { | ||
559 | __asm__ ( | ||
560 | " .set push \n" | ||
561 | " .set mips32 \n" | ||
562 | " clz %0, %1 \n" | ||
563 | " .set pop \n" | ||
564 | : "=r" (lz) | ||
565 | : "r" (x)); | ||
566 | |||
567 | return 31 - lz; | ||
568 | } | ||
569 | |||
570 | BUG_ON(sizeof(x) != 8); | ||
571 | |||
572 | __asm__ ( | ||
573 | " .set push \n" | ||
574 | " .set mips64 \n" | ||
575 | " dclz %0, %1 \n" | ||
576 | " .set pop \n" | ||
577 | : "=r" (lz) | ||
578 | : "r" (x)); | ||
579 | |||
580 | return 63 - lz; | ||
581 | } | ||
582 | |||
583 | /* | ||
584 | * __ffs - find first bit in word. | ||
527 | * @word: The word to search | 585 | * @word: The word to search |
528 | * | 586 | * |
529 | * Undefined if no zero exists, so code should check against ~0UL first. | 587 | * Returns 0..SZLONG-1 |
588 | * Undefined if no bit exists, so code should check against 0 first. | ||
530 | */ | 589 | */ |
531 | static inline unsigned long ffz(unsigned long word) | 590 | static inline unsigned long __ffs(unsigned long word) |
532 | { | 591 | { |
592 | #if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) | ||
593 | return __ilog2(word & -word); | ||
594 | #else | ||
533 | int b = 0, s; | 595 | int b = 0, s; |
534 | 596 | ||
535 | word = ~word; | ||
536 | #ifdef CONFIG_32BIT | 597 | #ifdef CONFIG_32BIT |
537 | s = 16; if (word << 16 != 0) s = 0; b += s; word >>= s; | 598 | s = 16; if (word << 16 != 0) s = 0; b += s; word >>= s; |
538 | s = 8; if (word << 24 != 0) s = 0; b += s; word >>= s; | 599 | s = 8; if (word << 24 != 0) s = 0; b += s; word >>= s; |
539 | s = 4; if (word << 28 != 0) s = 0; b += s; word >>= s; | 600 | s = 4; if (word << 28 != 0) s = 0; b += s; word >>= s; |
540 | s = 2; if (word << 30 != 0) s = 0; b += s; word >>= s; | 601 | s = 2; if (word << 30 != 0) s = 0; b += s; word >>= s; |
541 | s = 1; if (word << 31 != 0) s = 0; b += s; | 602 | s = 1; if (word << 31 != 0) s = 0; b += s; |
603 | |||
604 | return b; | ||
542 | #endif | 605 | #endif |
543 | #ifdef CONFIG_64BIT | 606 | #ifdef CONFIG_64BIT |
544 | s = 32; if (word << 32 != 0) s = 0; b += s; word >>= s; | 607 | s = 32; if (word << 32 != 0) s = 0; b += s; word >>= s; |
@@ -547,27 +610,92 @@ static inline unsigned long ffz(unsigned long word) | |||
547 | s = 4; if (word << 60 != 0) s = 0; b += s; word >>= s; | 610 | s = 4; if (word << 60 != 0) s = 0; b += s; word >>= s; |
548 | s = 2; if (word << 62 != 0) s = 0; b += s; word >>= s; | 611 | s = 2; if (word << 62 != 0) s = 0; b += s; word >>= s; |
549 | s = 1; if (word << 63 != 0) s = 0; b += s; | 612 | s = 1; if (word << 63 != 0) s = 0; b += s; |
550 | #endif | ||
551 | 613 | ||
552 | return b; | 614 | return b; |
615 | #endif | ||
616 | #endif | ||
553 | } | 617 | } |
554 | 618 | ||
555 | /* | 619 | /* |
556 | * __ffs - find first bit in word. | 620 | * ffs - find first bit set. |
557 | * @word: The word to search | 621 | * @word: The word to search |
558 | * | 622 | * |
559 | * Undefined if no bit exists, so code should check against 0 first. | 623 | * Returns 1..SZLONG |
624 | * Returns 0 if no bit exists | ||
560 | */ | 625 | */ |
561 | static inline unsigned long __ffs(unsigned long word) | 626 | |
627 | static inline unsigned long ffs(unsigned long word) | ||
562 | { | 628 | { |
563 | return ffz(~word); | 629 | if (!word) |
630 | return 0; | ||
631 | |||
632 | return __ffs(word) + 1; | ||
564 | } | 633 | } |
565 | 634 | ||
566 | /* | 635 | /* |
567 | * fls: find last bit set. | 636 | * ffz - find first zero in word. |
637 | * @word: The word to search | ||
638 | * | ||
639 | * Undefined if no zero exists, so code should check against ~0UL first. | ||
640 | */ | ||
641 | static inline unsigned long ffz(unsigned long word) | ||
642 | { | ||
643 | return __ffs (~word); | ||
644 | } | ||
645 | |||
646 | /* | ||
647 | * flz - find last zero in word. | ||
648 | * @word: The word to search | ||
649 | * | ||
650 | * Returns 0..SZLONG-1 | ||
651 | * Undefined if no zero exists, so code should check against ~0UL first. | ||
652 | */ | ||
653 | static inline unsigned long flz(unsigned long word) | ||
654 | { | ||
655 | #if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) | ||
656 | return __ilog2(~word); | ||
657 | #else | ||
658 | #ifdef CONFIG_32BIT | ||
659 | int r = 31, s; | ||
660 | word = ~word; | ||
661 | s = 16; if ((word & 0xffff0000)) s = 0; r -= s; word <<= s; | ||
662 | s = 8; if ((word & 0xff000000)) s = 0; r -= s; word <<= s; | ||
663 | s = 4; if ((word & 0xf0000000)) s = 0; r -= s; word <<= s; | ||
664 | s = 2; if ((word & 0xc0000000)) s = 0; r -= s; word <<= s; | ||
665 | s = 1; if ((word & 0x80000000)) s = 0; r -= s; | ||
666 | |||
667 | return r; | ||
668 | #endif | ||
669 | #ifdef CONFIG_64BIT | ||
670 | int r = 63, s; | ||
671 | word = ~word; | ||
672 | s = 32; if ((word & 0xffffffff00000000UL)) s = 0; r -= s; word <<= s; | ||
673 | s = 16; if ((word & 0xffff000000000000UL)) s = 0; r -= s; word <<= s; | ||
674 | s = 8; if ((word & 0xff00000000000000UL)) s = 0; r -= s; word <<= s; | ||
675 | s = 4; if ((word & 0xf000000000000000UL)) s = 0; r -= s; word <<= s; | ||
676 | s = 2; if ((word & 0xc000000000000000UL)) s = 0; r -= s; word <<= s; | ||
677 | s = 1; if ((word & 0x8000000000000000UL)) s = 0; r -= s; | ||
678 | |||
679 | return r; | ||
680 | #endif | ||
681 | #endif | ||
682 | } | ||
683 | |||
684 | /* | ||
685 | * fls - find last bit set. | ||
686 | * @word: The word to search | ||
687 | * | ||
688 | * Returns 1..SZLONG | ||
689 | * Returns 0 if no bit exists | ||
568 | */ | 690 | */ |
691 | static inline unsigned long fls(unsigned long word) | ||
692 | { | ||
693 | if (word == 0) | ||
694 | return 0; | ||
695 | |||
696 | return flz(~word) + 1; | ||
697 | } | ||
569 | 698 | ||
570 | #define fls(x) generic_fls(x) | ||
571 | 699 | ||
572 | /* | 700 | /* |
573 | * find_next_zero_bit - find the first zero bit in a memory region | 701 | * find_next_zero_bit - find the first zero bit in a memory region |
@@ -704,17 +832,6 @@ static inline int sched_find_first_bit(const unsigned long *b) | |||
704 | } | 832 | } |
705 | 833 | ||
706 | /* | 834 | /* |
707 | * ffs - find first bit set | ||
708 | * @x: the word to search | ||
709 | * | ||
710 | * This is defined the same way as | ||
711 | * the libc and compiler builtin ffs routines, therefore | ||
712 | * differs in spirit from the above ffz (man ffs). | ||
713 | */ | ||
714 | |||
715 | #define ffs(x) generic_ffs(x) | ||
716 | |||
717 | /* | ||
718 | * hweightN - returns the hamming weight of a N-bit word | 835 | * hweightN - returns the hamming weight of a N-bit word |
719 | * @x: the word to weigh | 836 | * @x: the word to weigh |
720 | * | 837 | * |