162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * From lib/bitmap.c 462306a36Sopenharmony_ci * Helper functions for bitmap.h. 562306a36Sopenharmony_ci */ 662306a36Sopenharmony_ci#include <linux/bitmap.h> 762306a36Sopenharmony_ci 862306a36Sopenharmony_ciunsigned int __bitmap_weight(const unsigned long *bitmap, int bits) 962306a36Sopenharmony_ci{ 1062306a36Sopenharmony_ci unsigned int k, w = 0, lim = bits/BITS_PER_LONG; 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci for (k = 0; k < lim; k++) 1362306a36Sopenharmony_ci w += hweight_long(bitmap[k]); 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci if (bits % BITS_PER_LONG) 1662306a36Sopenharmony_ci w += hweight_long(bitmap[k] & BITMAP_LAST_WORD_MASK(bits)); 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci return w; 1962306a36Sopenharmony_ci} 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_civoid __bitmap_or(unsigned long *dst, const unsigned long *bitmap1, 2262306a36Sopenharmony_ci const unsigned long *bitmap2, int bits) 2362306a36Sopenharmony_ci{ 2462306a36Sopenharmony_ci int k; 2562306a36Sopenharmony_ci int nr = BITS_TO_LONGS(bits); 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci for (k = 0; k < nr; k++) 2862306a36Sopenharmony_ci dst[k] = bitmap1[k] | bitmap2[k]; 2962306a36Sopenharmony_ci} 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_cisize_t bitmap_scnprintf(unsigned long *bitmap, unsigned int nbits, 3262306a36Sopenharmony_ci char *buf, size_t size) 3362306a36Sopenharmony_ci{ 3462306a36Sopenharmony_ci /* current bit is 'cur', most recently seen range is [rbot, rtop] */ 3562306a36Sopenharmony_ci unsigned int cur, rbot, rtop; 3662306a36Sopenharmony_ci bool first = true; 3762306a36Sopenharmony_ci size_t ret = 0; 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci rbot = cur = find_first_bit(bitmap, nbits); 4062306a36Sopenharmony_ci while (cur < nbits) { 4162306a36Sopenharmony_ci rtop = cur; 4262306a36Sopenharmony_ci cur = find_next_bit(bitmap, nbits, cur + 1); 4362306a36Sopenharmony_ci if (cur < nbits && cur <= rtop + 1) 4462306a36Sopenharmony_ci continue; 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci if (!first) 4762306a36Sopenharmony_ci ret += scnprintf(buf + ret, size - ret, ","); 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci first = false; 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci ret += scnprintf(buf + ret, size - ret, "%d", rbot); 5262306a36Sopenharmony_ci if (rbot < rtop) 5362306a36Sopenharmony_ci ret += scnprintf(buf + ret, size - ret, "-%d", rtop); 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci rbot = cur; 5662306a36Sopenharmony_ci } 5762306a36Sopenharmony_ci return ret; 5862306a36Sopenharmony_ci} 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_cibool __bitmap_and(unsigned long *dst, const unsigned long *bitmap1, 6162306a36Sopenharmony_ci const unsigned long *bitmap2, unsigned int bits) 6262306a36Sopenharmony_ci{ 6362306a36Sopenharmony_ci unsigned int k; 6462306a36Sopenharmony_ci unsigned int lim = bits/BITS_PER_LONG; 6562306a36Sopenharmony_ci unsigned long result = 0; 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci for (k = 0; k < lim; k++) 6862306a36Sopenharmony_ci result |= (dst[k] = bitmap1[k] & bitmap2[k]); 6962306a36Sopenharmony_ci if (bits % BITS_PER_LONG) 7062306a36Sopenharmony_ci result |= (dst[k] = bitmap1[k] & bitmap2[k] & 7162306a36Sopenharmony_ci BITMAP_LAST_WORD_MASK(bits)); 7262306a36Sopenharmony_ci return result != 0; 7362306a36Sopenharmony_ci} 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_cibool __bitmap_equal(const unsigned long *bitmap1, 7662306a36Sopenharmony_ci const unsigned long *bitmap2, unsigned int bits) 7762306a36Sopenharmony_ci{ 7862306a36Sopenharmony_ci unsigned int k, lim = bits/BITS_PER_LONG; 7962306a36Sopenharmony_ci for (k = 0; k < lim; ++k) 8062306a36Sopenharmony_ci if (bitmap1[k] != bitmap2[k]) 8162306a36Sopenharmony_ci return false; 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci if (bits % BITS_PER_LONG) 8462306a36Sopenharmony_ci if ((bitmap1[k] ^ bitmap2[k]) & BITMAP_LAST_WORD_MASK(bits)) 8562306a36Sopenharmony_ci return false; 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci return true; 8862306a36Sopenharmony_ci} 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_cibool __bitmap_intersects(const unsigned long *bitmap1, 9162306a36Sopenharmony_ci const unsigned long *bitmap2, unsigned int bits) 9262306a36Sopenharmony_ci{ 9362306a36Sopenharmony_ci unsigned int k, lim = bits/BITS_PER_LONG; 9462306a36Sopenharmony_ci for (k = 0; k < lim; ++k) 9562306a36Sopenharmony_ci if (bitmap1[k] & bitmap2[k]) 9662306a36Sopenharmony_ci return true; 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci if (bits % BITS_PER_LONG) 9962306a36Sopenharmony_ci if ((bitmap1[k] & bitmap2[k]) & BITMAP_LAST_WORD_MASK(bits)) 10062306a36Sopenharmony_ci return true; 10162306a36Sopenharmony_ci return false; 10262306a36Sopenharmony_ci} 103