* 2 of the License, or (at your option) any later version.
*/
+#include "qemu/osdep.h"
#include "qemu/bitops.h"
-#define BITOP_WORD(nr) ((nr) / BITS_PER_LONG)
-
/*
* Find the next set bit in a memory region.
*/
unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
- unsigned long offset)
+ unsigned long offset)
{
- const unsigned long *p = addr + BITOP_WORD(offset);
+ const unsigned long *p = addr + BIT_WORD(offset);
unsigned long result = offset & ~(BITS_PER_LONG-1);
unsigned long tmp;
size -= BITS_PER_LONG;
result += BITS_PER_LONG;
}
- while (size & ~(BITS_PER_LONG-1)) {
+ while (size >= 4*BITS_PER_LONG) {
+ unsigned long d1, d2, d3;
+ tmp = *p;
+ d1 = *(p+1);
+ d2 = *(p+2);
+ d3 = *(p+3);
+ if (tmp) {
+ goto found_middle;
+ }
+ if (d1 | d2 | d3) {
+ break;
+ }
+ p += 4;
+ result += 4*BITS_PER_LONG;
+ size -= 4*BITS_PER_LONG;
+ }
+ while (size >= BITS_PER_LONG) {
if ((tmp = *(p++))) {
goto found_middle;
}
return result + size; /* Nope. */
}
found_middle:
- return result + bitops_ffsl(tmp);
+ return result + ctzl(tmp);
}
/*
* Linus' asm-alpha/bitops.h.
*/
unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,
- unsigned long offset)
+ unsigned long offset)
{
- const unsigned long *p = addr + BITOP_WORD(offset);
+ const unsigned long *p = addr + BIT_WORD(offset);
unsigned long result = offset & ~(BITS_PER_LONG-1);
unsigned long tmp;
return result + size; /* Nope. */
}
found_middle:
- return result + ffz(tmp);
+ return result + ctzl(~tmp);
}
unsigned long find_last_bit(const unsigned long *addr, unsigned long size)
tmp = addr[--words];
if (tmp) {
found:
- return words * BITS_PER_LONG + bitops_flsl(tmp);
+ return words * BITS_PER_LONG + BITS_PER_LONG - 1 - clzl(tmp);
}
}