summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorMiles Bader <miles@mctpc71.ucom.lsi.nec.co.jp>2004-06-25 00:54:42 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-06-25 00:54:42 -0700
commit10d8131a70773fd9e0fbfb67822c8fba4d14c829 (patch)
tree1bf0eada4bea55e8cb33400aee211e7380c84327 /include
parentecd8b3c6b5b557c9306186f1d41b85f61ec54254 (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.h76
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