xref: /openbmc/linux/tools/lib/bitmap.c (revision e3b9f1e8)
1 /*
2  * From lib/bitmap.c
3  * Helper functions for bitmap.h.
4  *
5  * This source code is licensed under the GNU General Public License,
6  * Version 2.  See the file COPYING for more details.
7  */
8 #include <linux/bitmap.h>
9 
10 int __bitmap_weight(const unsigned long *bitmap, int bits)
11 {
12 	int k, w = 0, lim = bits/BITS_PER_LONG;
13 
14 	for (k = 0; k < lim; k++)
15 		w += hweight_long(bitmap[k]);
16 
17 	if (bits % BITS_PER_LONG)
18 		w += hweight_long(bitmap[k] & BITMAP_LAST_WORD_MASK(bits));
19 
20 	return w;
21 }
22 
23 void __bitmap_or(unsigned long *dst, const unsigned long *bitmap1,
24 		 const unsigned long *bitmap2, int bits)
25 {
26 	int k;
27 	int nr = BITS_TO_LONGS(bits);
28 
29 	for (k = 0; k < nr; k++)
30 		dst[k] = bitmap1[k] | bitmap2[k];
31 }
32 
33 size_t bitmap_scnprintf(unsigned long *bitmap, int nbits,
34 			char *buf, size_t size)
35 {
36 	/* current bit is 'cur', most recently seen range is [rbot, rtop] */
37 	int cur, rbot, rtop;
38 	bool first = true;
39 	size_t ret = 0;
40 
41 	rbot = cur = find_first_bit(bitmap, nbits);
42 	while (cur < nbits) {
43 		rtop = cur;
44 		cur = find_next_bit(bitmap, nbits, cur + 1);
45 		if (cur < nbits && cur <= rtop + 1)
46 			continue;
47 
48 		if (!first)
49 			ret += scnprintf(buf + ret, size - ret, ",");
50 
51 		first = false;
52 
53 		ret += scnprintf(buf + ret, size - ret, "%d", rbot);
54 		if (rbot < rtop)
55 			ret += scnprintf(buf + ret, size - ret, "-%d", rtop);
56 
57 		rbot = cur;
58 	}
59 	return ret;
60 }
61 
62 int __bitmap_and(unsigned long *dst, const unsigned long *bitmap1,
63 		 const unsigned long *bitmap2, unsigned int bits)
64 {
65 	unsigned int k;
66 	unsigned int lim = bits/BITS_PER_LONG;
67 	unsigned long result = 0;
68 
69 	for (k = 0; k < lim; k++)
70 		result |= (dst[k] = bitmap1[k] & bitmap2[k]);
71 	if (bits % BITS_PER_LONG)
72 		result |= (dst[k] = bitmap1[k] & bitmap2[k] &
73 			   BITMAP_LAST_WORD_MASK(bits));
74 	return result != 0;
75 }
76