xref: /kvm-unit-tests/lib/bitops.h (revision 8a97884a2a8b84ac52dc10d0921760af3071e0ce)
1 #ifndef _BITOPS_H_
2 #define _BITOPS_H_
3 
4 #include <stdbool.h>
5 #include <stddef.h>
6 
7 /*
8  * Adapted from
9  *   include/linux/bitops.h
10  *
11  * Copyright (C) 2017, Red Hat Inc, Andrew Jones <drjones@redhat.com>
12  *
13  * This work is licensed under the terms of the GNU GPL, version 2.
14  */
15 
16 #define BITS_PER_LONG_LONG	64
17 #define BIT(nr)			(1UL << (nr))
18 #define BIT_ULL(nr)		(1ULL << (nr))
19 #define BIT_MASK(nr)		(1UL << ((nr) % BITS_PER_LONG))
20 #define BIT_WORD(nr)		((nr) / BITS_PER_LONG)
21 #define BIT_ULL_MASK(nr)	(1ULL << ((nr) % BITS_PER_LONG_LONG))
22 #define BIT_ULL_WORD(nr)	((nr) / BITS_PER_LONG_LONG)
23 #define BITS_PER_BYTE		8
24 #define BITS_TO_LONGS(nr)	DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
25 
26 #include <asm/bitops.h>
27 
28 /*
29  * Create a contiguous bitmask starting at bit position @l and ending at
30  * position @h. For example
31  * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000.
32  */
33 #define GENMASK(h, l) \
34 	(((~0UL) << (l)) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
35 
36 #define GENMASK_ULL(h, l) \
37 	(((~0ULL) << (l)) & (~0ULL >> (BITS_PER_LONG_LONG - 1 - (h))))
38 
39 #define upper_32_bits(n) ((u32)(((n) >> 16) >> 16))
40 #define lower_32_bits(n) ((u32)(n))
41 
42 #ifndef HAVE_BUILTIN_FLS
fls(unsigned long word)43 static inline unsigned long fls(unsigned long word)
44 {
45 	int num = BITS_PER_LONG - 1;
46 
47 #if BITS_PER_LONG == 64
48 	if (!(word & (~0ul << 32))) {
49 		num -= 32;
50 		word <<= 32;
51 	}
52 #endif
53 	if (!(word & (~0ul << (BITS_PER_LONG-16)))) {
54 		num -= 16;
55 		word <<= 16;
56 	}
57 	if (!(word & (~0ul << (BITS_PER_LONG-8)))) {
58 		num -= 8;
59 		word <<= 8;
60 	}
61 	if (!(word & (~0ul << (BITS_PER_LONG-4)))) {
62 		num -= 4;
63 		word <<= 4;
64 	}
65 	if (!(word & (~0ul << (BITS_PER_LONG-2)))) {
66 		num -= 2;
67 		word <<= 2;
68 	}
69 	if (!(word & (~0ul << (BITS_PER_LONG-1))))
70 		num -= 1;
71 	return num;
72 }
73 #else
fls(unsigned long word)74 static inline unsigned long fls(unsigned long word)
75 {
76 	return BITS_PER_LONG - __builtin_clzl(word) - 1;
77 }
78 #endif
79 
is_power_of_2(unsigned long n)80 static inline bool is_power_of_2(unsigned long n)
81 {
82 	return n && !(n & (n - 1));
83 }
84 
get_order(size_t size)85 static inline unsigned int get_order(size_t size)
86 {
87 	return size ? fls(size) + !is_power_of_2(size) : 0;
88 }
89 
90 #endif
91