diff options
| author | Miles Bader <miles@mctpc71.ucom.lsi.nec.co.jp> | 2004-06-25 00:54:42 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-06-25 00:54:42 -0700 |
| commit | 10d8131a70773fd9e0fbfb67822c8fba4d14c829 (patch) | |
| tree | 1bf0eada4bea55e8cb33400aee211e7380c84327 /include | |
| parent | ecd8b3c6b5b557c9306186f1d41b85f61ec54254 (diff) | |
[PATCH] v850: add find_next_bit
[Since many archs use the same implementation of find_next_bit, it might
be nice to have `generic_find_next_bit' or something.]
Signed-off-by: Miles Bader <miles@gnu.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include')
| -rw-r--r-- | include/asm-v850/bitops.h | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/include/asm-v850/bitops.h b/include/asm-v850/bitops.h index c837ea08c611..5ca65390186b 100644 --- a/include/asm-v850/bitops.h +++ b/include/asm-v850/bitops.h @@ -193,10 +193,86 @@ extern __inline__ int find_next_zero_bit (void *addr, int size, int offset) return result + ffz (tmp); } + +/* This is the same as generic_ffs, but we can't use that because it's + inline and the #include order mucks things up. */ +static inline int generic_ffs_for_find_next_bit(int x) +{ + int r = 1; + + if (!x) + return 0; + if (!(x & 0xffff)) { + x >>= 16; + r += 16; + } + if (!(x & 0xff)) { + x >>= 8; + r += 8; + } + if (!(x & 0xf)) { + x >>= 4; + r += 4; + } + if (!(x & 3)) { + x >>= 2; + r += 2; + } + if (!(x & 1)) { + x >>= 1; + r += 1; + } + return r; +} + +/* + * Find next one bit in a bitmap reasonably efficiently. + */ +static __inline__ unsigned long find_next_bit(const unsigned long *addr, + unsigned long size, unsigned long offset) +{ + unsigned int *p = ((unsigned int *) addr) + (offset >> 5); + unsigned int result = offset & ~31UL; + unsigned int tmp; + + if (offset >= size) + return size; + size -= result; + offset &= 31UL; + if (offset) { + tmp = *p++; + tmp &= ~0UL << offset; + if (size < 32) + goto found_first; + if (tmp) + goto found_middle; + size -= 32; + result += 32; + } + while (size >= 32) { + if ((tmp = *p++) != 0) + goto found_middle; + result += 32; + size -= 32; + } + if (!size) + return result; + tmp = *p; + +found_first: + tmp &= ~0UL >> (32 - size); + if (tmp == 0UL) /* Are any bits set? */ + return result + size; /* Nope. */ +found_middle: + return result + generic_ffs_for_find_next_bit(tmp); +} + + #define ffs(x) generic_ffs (x) #define fls(x) generic_fls (x) #define __ffs(x) ffs(x) + /* * This is just `generic_ffs' from <linux/bitops.h>, except that it assumes * that at least one bit is set, and returns the real index of the bit |
