Linux Audio

Check our new training course

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