18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * From lib/bitmap.c
48c2ecf20Sopenharmony_ci * Helper functions for bitmap.h.
58c2ecf20Sopenharmony_ci */
68c2ecf20Sopenharmony_ci#include <linux/bitmap.h>
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ciint __bitmap_weight(const unsigned long *bitmap, int bits)
98c2ecf20Sopenharmony_ci{
108c2ecf20Sopenharmony_ci	int k, w = 0, lim = bits/BITS_PER_LONG;
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci	for (k = 0; k < lim; k++)
138c2ecf20Sopenharmony_ci		w += hweight_long(bitmap[k]);
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci	if (bits % BITS_PER_LONG)
168c2ecf20Sopenharmony_ci		w += hweight_long(bitmap[k] & BITMAP_LAST_WORD_MASK(bits));
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci	return w;
198c2ecf20Sopenharmony_ci}
208c2ecf20Sopenharmony_ci
218c2ecf20Sopenharmony_civoid __bitmap_or(unsigned long *dst, const unsigned long *bitmap1,
228c2ecf20Sopenharmony_ci		 const unsigned long *bitmap2, int bits)
238c2ecf20Sopenharmony_ci{
248c2ecf20Sopenharmony_ci	int k;
258c2ecf20Sopenharmony_ci	int nr = BITS_TO_LONGS(bits);
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ci	for (k = 0; k < nr; k++)
288c2ecf20Sopenharmony_ci		dst[k] = bitmap1[k] | bitmap2[k];
298c2ecf20Sopenharmony_ci}
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_cisize_t bitmap_scnprintf(unsigned long *bitmap, int nbits,
328c2ecf20Sopenharmony_ci			char *buf, size_t size)
338c2ecf20Sopenharmony_ci{
348c2ecf20Sopenharmony_ci	/* current bit is 'cur', most recently seen range is [rbot, rtop] */
358c2ecf20Sopenharmony_ci	int cur, rbot, rtop;
368c2ecf20Sopenharmony_ci	bool first = true;
378c2ecf20Sopenharmony_ci	size_t ret = 0;
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci	rbot = cur = find_first_bit(bitmap, nbits);
408c2ecf20Sopenharmony_ci	while (cur < nbits) {
418c2ecf20Sopenharmony_ci		rtop = cur;
428c2ecf20Sopenharmony_ci		cur = find_next_bit(bitmap, nbits, cur + 1);
438c2ecf20Sopenharmony_ci		if (cur < nbits && cur <= rtop + 1)
448c2ecf20Sopenharmony_ci			continue;
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci		if (!first)
478c2ecf20Sopenharmony_ci			ret += scnprintf(buf + ret, size - ret, ",");
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ci		first = false;
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci		ret += scnprintf(buf + ret, size - ret, "%d", rbot);
528c2ecf20Sopenharmony_ci		if (rbot < rtop)
538c2ecf20Sopenharmony_ci			ret += scnprintf(buf + ret, size - ret, "-%d", rtop);
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci		rbot = cur;
568c2ecf20Sopenharmony_ci	}
578c2ecf20Sopenharmony_ci	return ret;
588c2ecf20Sopenharmony_ci}
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_ciint __bitmap_and(unsigned long *dst, const unsigned long *bitmap1,
618c2ecf20Sopenharmony_ci		 const unsigned long *bitmap2, unsigned int bits)
628c2ecf20Sopenharmony_ci{
638c2ecf20Sopenharmony_ci	unsigned int k;
648c2ecf20Sopenharmony_ci	unsigned int lim = bits/BITS_PER_LONG;
658c2ecf20Sopenharmony_ci	unsigned long result = 0;
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ci	for (k = 0; k < lim; k++)
688c2ecf20Sopenharmony_ci		result |= (dst[k] = bitmap1[k] & bitmap2[k]);
698c2ecf20Sopenharmony_ci	if (bits % BITS_PER_LONG)
708c2ecf20Sopenharmony_ci		result |= (dst[k] = bitmap1[k] & bitmap2[k] &
718c2ecf20Sopenharmony_ci			   BITMAP_LAST_WORD_MASK(bits));
728c2ecf20Sopenharmony_ci	return result != 0;
738c2ecf20Sopenharmony_ci}
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_ciint __bitmap_equal(const unsigned long *bitmap1,
768c2ecf20Sopenharmony_ci		const unsigned long *bitmap2, unsigned int bits)
778c2ecf20Sopenharmony_ci{
788c2ecf20Sopenharmony_ci	unsigned int k, lim = bits/BITS_PER_LONG;
798c2ecf20Sopenharmony_ci	for (k = 0; k < lim; ++k)
808c2ecf20Sopenharmony_ci		if (bitmap1[k] != bitmap2[k])
818c2ecf20Sopenharmony_ci			return 0;
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_ci	if (bits % BITS_PER_LONG)
848c2ecf20Sopenharmony_ci		if ((bitmap1[k] ^ bitmap2[k]) & BITMAP_LAST_WORD_MASK(bits))
858c2ecf20Sopenharmony_ci			return 0;
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_ci	return 1;
888c2ecf20Sopenharmony_ci}
89