xref: /openbsd/sys/dev/pci/drm/include/linux/bitmap.h (revision 46b28811)
1*46b28811Sbluhm /*	$OpenBSD: bitmap.h,v 1.8 2024/03/20 22:52:44 bluhm Exp $	*/
27f4dd379Sjsg /*
37f4dd379Sjsg  * Copyright (c) 2013, 2014, 2015 Mark Kettenis
47f4dd379Sjsg  *
57f4dd379Sjsg  * Permission to use, copy, modify, and distribute this software for any
67f4dd379Sjsg  * purpose with or without fee is hereby granted, provided that the above
77f4dd379Sjsg  * copyright notice and this permission notice appear in all copies.
87f4dd379Sjsg  *
97f4dd379Sjsg  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
107f4dd379Sjsg  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
117f4dd379Sjsg  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
127f4dd379Sjsg  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
137f4dd379Sjsg  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
147f4dd379Sjsg  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
157f4dd379Sjsg  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
167f4dd379Sjsg  */
177f4dd379Sjsg 
187f4dd379Sjsg #ifndef _LINUX_BITMAP_H
197f4dd379Sjsg #define _LINUX_BITMAP_H
207f4dd379Sjsg 
21667382c7Skettenis #include <linux/align.h>
227f4dd379Sjsg #include <linux/bitops.h>
230001c2c8Sjsg #include <linux/string.h>
247f4dd379Sjsg 
257f4dd379Sjsg #define bitmap_empty(p, n)	(find_first_bit(p, n) == n)
267f4dd379Sjsg 
277f4dd379Sjsg static inline void
bitmap_set(void * p,int b,u_int n)287f4dd379Sjsg bitmap_set(void *p, int b, u_int n)
297f4dd379Sjsg {
307f4dd379Sjsg 	u_int end = b + n;
317f4dd379Sjsg 
327f4dd379Sjsg 	for (; b < end; b++)
337f4dd379Sjsg 		__set_bit(b, p);
347f4dd379Sjsg }
357f4dd379Sjsg 
367f4dd379Sjsg static inline void
bitmap_clear(void * p,int b,u_int n)377f4dd379Sjsg bitmap_clear(void *p, int b, u_int n)
387f4dd379Sjsg {
397f4dd379Sjsg 	u_int end = b + n;
407f4dd379Sjsg 
417f4dd379Sjsg 	for (; b < end; b++)
427f4dd379Sjsg 		__clear_bit(b, p);
437f4dd379Sjsg }
447f4dd379Sjsg 
457f4dd379Sjsg static inline void
bitmap_zero(void * p,u_int n)467f4dd379Sjsg bitmap_zero(void *p, u_int n)
477f4dd379Sjsg {
487f4dd379Sjsg 	u_int *ptr = p;
497f4dd379Sjsg 	u_int b;
507f4dd379Sjsg 
517f4dd379Sjsg 	for (b = 0; b < n; b += 32)
527f4dd379Sjsg 		ptr[b >> 5] = 0;
537f4dd379Sjsg }
547f4dd379Sjsg 
557f4dd379Sjsg static inline void
bitmap_fill(void * p,u_int n)561bb76ff1Sjsg bitmap_fill(void *p, u_int n)
571bb76ff1Sjsg {
581bb76ff1Sjsg 	u_int *ptr = p;
591bb76ff1Sjsg 	u_int b;
601bb76ff1Sjsg 
611bb76ff1Sjsg 	for (b = 0; b < n; b += 32)
621bb76ff1Sjsg 		ptr[b >> 5] = 0xffffffff;
631bb76ff1Sjsg }
641bb76ff1Sjsg 
651bb76ff1Sjsg static inline void
bitmap_or(void * d,void * s1,void * s2,u_int n)667f4dd379Sjsg bitmap_or(void *d, void *s1, void *s2, u_int n)
677f4dd379Sjsg {
687f4dd379Sjsg 	u_int *dst = d;
697f4dd379Sjsg 	u_int *src1 = s1;
707f4dd379Sjsg 	u_int *src2 = s2;
717f4dd379Sjsg 	u_int b;
727f4dd379Sjsg 
737f4dd379Sjsg 	for (b = 0; b < n; b += 32)
747f4dd379Sjsg 		dst[b >> 5] = src1[b >> 5] | src2[b >> 5];
757f4dd379Sjsg }
767f4dd379Sjsg 
777f4dd379Sjsg static inline void
bitmap_andnot(void * d,void * s1,void * s2,u_int n)78c349dbc7Sjsg bitmap_andnot(void *d, void *s1, void *s2, u_int n)
79c349dbc7Sjsg {
80c349dbc7Sjsg 	u_int *dst = d;
81c349dbc7Sjsg 	u_int *src1 = s1;
82c349dbc7Sjsg 	u_int *src2 = s2;
83c349dbc7Sjsg 	u_int b;
84c349dbc7Sjsg 
85c349dbc7Sjsg 	for (b = 0; b < n; b += 32)
86c349dbc7Sjsg 		dst[b >> 5] = src1[b >> 5] & ~src2[b >> 5];
87c349dbc7Sjsg }
88c349dbc7Sjsg 
89c349dbc7Sjsg static inline void
bitmap_complement(void * d,void * s,u_int n)907f4dd379Sjsg bitmap_complement(void *d, void *s, u_int n)
917f4dd379Sjsg {
927f4dd379Sjsg 	u_int *dst = d;
937f4dd379Sjsg 	u_int *src = s;
947f4dd379Sjsg 	u_int b;
957f4dd379Sjsg 
967f4dd379Sjsg 	for (b = 0; b < n; b += 32)
977f4dd379Sjsg 		dst[b >> 5] = ~src[b >> 5];
987f4dd379Sjsg }
997f4dd379Sjsg 
10010309c38Sjsg static inline bool
bitmap_intersects(const void * s1,const void * s2,u_int n)10110309c38Sjsg bitmap_intersects(const void *s1, const void *s2, u_int n)
10210309c38Sjsg {
10310309c38Sjsg 	const u_int *b1 = s1;
10410309c38Sjsg 	const u_int *b2 = s2;
10510309c38Sjsg 	u_int b;
10610309c38Sjsg 
10710309c38Sjsg 	for (b = 0; b < n; b += 32)
10810309c38Sjsg 		if (b1[b >> 5] & b2[b >> 5])
10910309c38Sjsg 			return true;
11010309c38Sjsg 	if ((n % 32) != 0)
11110309c38Sjsg 		if ((b1[n >> 5] & b2[b >> 5]) & (0xffffffff >> (32 - (n % 32))))
11210309c38Sjsg 			return true;
11310309c38Sjsg 
11410309c38Sjsg 	return false;
11510309c38Sjsg }
11610309c38Sjsg 
117c349dbc7Sjsg static inline void
bitmap_copy(void * d,const void * s,u_int n)118*46b28811Sbluhm bitmap_copy(void *d, const void *s, u_int n)
119c349dbc7Sjsg {
120c349dbc7Sjsg 	u_int *dst = d;
121*46b28811Sbluhm 	const u_int *src = s;
122c349dbc7Sjsg 	u_int b;
123c349dbc7Sjsg 
124c349dbc7Sjsg 	for (b = 0; b < n; b += 32)
125c349dbc7Sjsg 		dst[b >> 5] = src[b >> 5];
126c349dbc7Sjsg }
127c349dbc7Sjsg 
12883eea38aSjsg static inline void
bitmap_to_arr32(void * d,const unsigned long * src,u_int n)12910309c38Sjsg bitmap_to_arr32(void *d, const unsigned long *src, u_int n)
13083eea38aSjsg {
13183eea38aSjsg 	u_int *dst = d;
13283eea38aSjsg 	u_int b;
13383eea38aSjsg 
13483eea38aSjsg #ifdef __LP64__
13583eea38aSjsg 	for (b = 0; b < n; b += 32) {
13683eea38aSjsg 		dst[b >> 5] = src[b >> 6] & 0xffffffff;
13783eea38aSjsg 		b += 32;
13883eea38aSjsg 		if (b < n)
13983eea38aSjsg 			dst[b >> 5] = src[b >> 6] >> 32;
14083eea38aSjsg 	}
14183eea38aSjsg #else
14283eea38aSjsg 	bitmap_copy(d, src, n);
14383eea38aSjsg #endif
14483eea38aSjsg 	if ((n % 32) != 0)
14583eea38aSjsg 		dst[n >> 5] &= (0xffffffff >> (32 - (n % 32)));
14683eea38aSjsg }
14783eea38aSjsg 
14810309c38Sjsg static inline void
bitmap_from_arr32(unsigned long * dst,const void * s,u_int n)14910309c38Sjsg bitmap_from_arr32(unsigned long *dst, const void *s, u_int n)
15010309c38Sjsg {
15110309c38Sjsg 	const u_int *src = s;
15210309c38Sjsg 	u_int b;
15310309c38Sjsg 
15410309c38Sjsg #ifdef __LP64__
15510309c38Sjsg 	for (b = 0; b < n; b += 32) {
15610309c38Sjsg 		dst[b >> 6] = src[b >> 5];
15710309c38Sjsg 		b += 32;
15810309c38Sjsg 		if (b < n)
15910309c38Sjsg 			dst[b >> 6] |= ((unsigned long)src[b >> 5]) << 32;
16010309c38Sjsg 	}
16110309c38Sjsg 	if ((n % 64) != 0)
16210309c38Sjsg 		dst[n >> 6] &= (0xffffffffffffffffUL >> (64 - (n % 64)));
16310309c38Sjsg #else
16410309c38Sjsg 	bitmap_copy(dst, s, n);
16510309c38Sjsg 	if ((n % 32) != 0)
16610309c38Sjsg 		dst[n >> 5] &=  (0xffffffff >> (32 - (n % 32)));
16710309c38Sjsg #endif
16810309c38Sjsg }
16983eea38aSjsg 
1707f4dd379Sjsg static inline int
bitmap_weight(const void * p,u_int n)1711bb76ff1Sjsg bitmap_weight(const void *p, u_int n)
1727f4dd379Sjsg {
1731bb76ff1Sjsg 	const u_int *ptr = p;
1747f4dd379Sjsg 	u_int b;
1757f4dd379Sjsg 	int sum = 0;
1767f4dd379Sjsg 
1777f4dd379Sjsg 	for (b = 0; b < n; b += 32)
1787f4dd379Sjsg 		sum += hweight32(ptr[b >> 5]);
1797f4dd379Sjsg 	return sum;
1807f4dd379Sjsg }
1817f4dd379Sjsg 
182667382c7Skettenis static inline int
bitmap_find_free_region(void * p,u_int n,int o)183667382c7Skettenis bitmap_find_free_region(void *p, u_int n, int o)
184667382c7Skettenis {
185667382c7Skettenis 	int b;
186667382c7Skettenis 
187667382c7Skettenis 	KASSERT(o == 0);
188667382c7Skettenis 	b = find_first_zero_bit(p, n);
189667382c7Skettenis 	if (b == n)
190667382c7Skettenis 		return -ENOMEM;
191667382c7Skettenis 	__set_bit(b, p);
192667382c7Skettenis 	return b;
193667382c7Skettenis }
194667382c7Skettenis 
195667382c7Skettenis static inline void
bitmap_release_region(void * p,u_int b,int o)196667382c7Skettenis bitmap_release_region(void *p, u_int b, int o)
197667382c7Skettenis {
198667382c7Skettenis 	KASSERT(o == 0);
199667382c7Skettenis 	__clear_bit(b, p);
200667382c7Skettenis }
201667382c7Skettenis 
202c349dbc7Sjsg void *bitmap_zalloc(u_int, gfp_t);
203c349dbc7Sjsg void bitmap_free(void *);
204c349dbc7Sjsg 
2057f4dd379Sjsg #endif
206