1/*
2 * MSB0 numbered special bitops handling.
3 *
4 * The bits are numbered:
5 *   |0..............63|64............127|128...........191|192...........255|
6 *
7 * The reason for this bit numbering is the fact that the hardware sets bits
8 * in a bitmap starting at bit 0 (MSB) and we don't want to scan the bitmap
9 * from the 'wrong end'.
10 */
11
12#include <linux/compiler.h>
13#include <linux/bitops.h>
14#include <linux/export.h>
15
16unsigned long find_first_bit_inv(const unsigned long *addr, unsigned long size)
17{
18	const unsigned long *p = addr;
19	unsigned long result = 0;
20	unsigned long tmp;
21
22	while (size & ~(BITS_PER_LONG - 1)) {
23		if ((tmp = *(p++)))
24			goto found;
25		result += BITS_PER_LONG;
26		size -= BITS_PER_LONG;
27	}
28	if (!size)
29		return result;
30	tmp = (*p) & (~0UL << (BITS_PER_LONG - size));
31	if (!tmp)		/* Are any bits set? */
32		return result + size;	/* Nope. */
33found:
34	return result + (__fls(tmp) ^ (BITS_PER_LONG - 1));
35}
36EXPORT_SYMBOL(find_first_bit_inv);
37
38unsigned long find_next_bit_inv(const unsigned long *addr, unsigned long size,
39				unsigned long offset)
40{
41	const unsigned long *p = addr + (offset / BITS_PER_LONG);
42	unsigned long result = offset & ~(BITS_PER_LONG - 1);
43	unsigned long tmp;
44
45	if (offset >= size)
46		return size;
47	size -= result;
48	offset %= BITS_PER_LONG;
49	if (offset) {
50		tmp = *(p++);
51		tmp &= (~0UL >> offset);
52		if (size < BITS_PER_LONG)
53			goto found_first;
54		if (tmp)
55			goto found_middle;
56		size -= BITS_PER_LONG;
57		result += BITS_PER_LONG;
58	}
59	while (size & ~(BITS_PER_LONG-1)) {
60		if ((tmp = *(p++)))
61			goto found_middle;
62		result += BITS_PER_LONG;
63		size -= BITS_PER_LONG;
64	}
65	if (!size)
66		return result;
67	tmp = *p;
68found_first:
69	tmp &= (~0UL << (BITS_PER_LONG - size));
70	if (!tmp)		/* Are any bits set? */
71		return result + size;	/* Nope. */
72found_middle:
73	return result + (__fls(tmp) ^ (BITS_PER_LONG - 1));
74}
75EXPORT_SYMBOL(find_next_bit_inv);
76