bitops.h 5.6 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4
#ifndef _LINUX_BITOPS_H
#define _LINUX_BITOPS_H
#include <asm/types.h>

5
#ifdef	__KERNEL__
J
Jiri Slaby 已提交
6
#define BIT(nr)			(1UL << (nr))
7
#define BIT_ULL(nr)		(1ULL << (nr))
8 9
#define BIT_MASK(nr)		(1UL << ((nr) % BITS_PER_LONG))
#define BIT_WORD(nr)		((nr) / BITS_PER_LONG)
10 11
#define BIT_ULL_MASK(nr)	(1ULL << ((nr) % BITS_PER_LONG_LONG))
#define BIT_ULL_WORD(nr)	((nr) / BITS_PER_LONG_LONG)
12
#define BITS_PER_BYTE		8
13
#define BITS_TO_LONGS(nr)	DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
14 15
#endif

16 17 18 19 20
/*
 * Create a contiguous bitmask starting at bit position @l and ending at
 * position @h. For example
 * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000.
 */
21 22 23 24 25
#define GENMASK(h, l) \
	(((~0UL) << (l)) & (~0UL >> (BITS_PER_LONG - 1 - (h))))

#define GENMASK_ULL(h, l) \
	(((~0ULL) << (l)) & (~0ULL >> (BITS_PER_LONG_LONG - 1 - (h))))
26

27 28 29 30 31
extern unsigned int __sw_hweight8(unsigned int w);
extern unsigned int __sw_hweight16(unsigned int w);
extern unsigned int __sw_hweight32(unsigned int w);
extern unsigned long __sw_hweight64(__u64 w);

L
Linus Torvalds 已提交
32 33 34 35 36 37
/*
 * Include this here because some architectures need generic_ffs/fls in
 * scope
 */
#include <asm/bitops.h>

38
#define for_each_set_bit(bit, addr, size) \
39 40 41 42 43
	for ((bit) = find_first_bit((addr), (size));		\
	     (bit) < (size);					\
	     (bit) = find_next_bit((addr), (size), (bit) + 1))

/* same as for_each_set_bit() but use bit as value to start with */
44
#define for_each_set_bit_from(bit, addr, size) \
45 46
	for ((bit) = find_next_bit((addr), (size), (bit));	\
	     (bit) < (size);					\
47 48
	     (bit) = find_next_bit((addr), (size), (bit) + 1))

49 50 51 52 53 54 55 56 57 58 59
#define for_each_clear_bit(bit, addr, size) \
	for ((bit) = find_first_zero_bit((addr), (size));	\
	     (bit) < (size);					\
	     (bit) = find_next_zero_bit((addr), (size), (bit) + 1))

/* same as for_each_clear_bit() but use bit as value to start with */
#define for_each_clear_bit_from(bit, addr, size) \
	for ((bit) = find_next_zero_bit((addr), (size), (bit));	\
	     (bit) < (size);					\
	     (bit) = find_next_zero_bit((addr), (size), (bit) + 1))

60
static inline int get_bitmask_order(unsigned int count)
L
Linus Torvalds 已提交
61 62
{
	int order;
63

L
Linus Torvalds 已提交
64 65 66 67
	order = fls(count);
	return order;	/* We could be slightly more clever with -1 here... */
}

68
static inline int get_count_order(unsigned int count)
69 70
{
	int order;
71

72 73 74 75 76 77
	order = fls(count) - 1;
	if (count & (count - 1))
		order++;
	return order;
}

78
static __always_inline unsigned long hweight_long(unsigned long w)
L
Linus Torvalds 已提交
79
{
80
	return sizeof(w) == 4 ? hweight32(w) : hweight64(w);
L
Linus Torvalds 已提交
81 82
}

83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
/**
 * rol64 - rotate a 64-bit value left
 * @word: value to rotate
 * @shift: bits to roll
 */
static inline __u64 rol64(__u64 word, unsigned int shift)
{
	return (word << shift) | (word >> (64 - shift));
}

/**
 * ror64 - rotate a 64-bit value right
 * @word: value to rotate
 * @shift: bits to roll
 */
static inline __u64 ror64(__u64 word, unsigned int shift)
{
	return (word >> shift) | (word << (64 - shift));
}

103
/**
L
Linus Torvalds 已提交
104 105 106 107 108 109 110 111 112
 * rol32 - rotate a 32-bit value left
 * @word: value to rotate
 * @shift: bits to roll
 */
static inline __u32 rol32(__u32 word, unsigned int shift)
{
	return (word << shift) | (word >> (32 - shift));
}

113
/**
L
Linus Torvalds 已提交
114 115 116 117 118 119 120 121 122
 * ror32 - rotate a 32-bit value right
 * @word: value to rotate
 * @shift: bits to roll
 */
static inline __u32 ror32(__u32 word, unsigned int shift)
{
	return (word >> shift) | (word << (32 - shift));
}

123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
/**
 * rol16 - rotate a 16-bit value left
 * @word: value to rotate
 * @shift: bits to roll
 */
static inline __u16 rol16(__u16 word, unsigned int shift)
{
	return (word << shift) | (word >> (16 - shift));
}

/**
 * ror16 - rotate a 16-bit value right
 * @word: value to rotate
 * @shift: bits to roll
 */
static inline __u16 ror16(__u16 word, unsigned int shift)
{
	return (word >> shift) | (word << (16 - shift));
}

/**
 * rol8 - rotate an 8-bit value left
 * @word: value to rotate
 * @shift: bits to roll
 */
static inline __u8 rol8(__u8 word, unsigned int shift)
{
	return (word << shift) | (word >> (8 - shift));
}

/**
 * ror8 - rotate an 8-bit value right
 * @word: value to rotate
 * @shift: bits to roll
 */
static inline __u8 ror8(__u8 word, unsigned int shift)
{
	return (word >> shift) | (word << (8 - shift));
}
162 163 164 165 166 167 168 169 170 171 172

/**
 * sign_extend32 - sign extend a 32-bit value using specified bit as sign-bit
 * @value: value to sign extend
 * @index: 0 based bit index (0<=index<32) to sign bit
 */
static inline __s32 sign_extend32(__u32 value, int index)
{
	__u8 shift = 31 - index;
	return (__s32)(value << shift) >> shift;
}
173

174 175 176 177 178 179 180
static inline unsigned fls_long(unsigned long l)
{
	if (sizeof(l) == 4)
		return fls(l);
	return fls64(l);
}

181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
/**
 * __ffs64 - find first set bit in a 64 bit word
 * @word: The 64 bit word
 *
 * On 64 bit arches this is a synomyn for __ffs
 * The result is not defined if no bits are set, so check that @word
 * is non-zero before calling this.
 */
static inline unsigned long __ffs64(u64 word)
{
#if BITS_PER_LONG == 32
	if (((u32)word) == 0UL)
		return __ffs((u32)(word >> 32)) + 32;
#elif BITS_PER_LONG != 64
#error BITS_PER_LONG not 32 or 64
#endif
	return __ffs((unsigned long)word);
}

200
#ifdef __KERNEL__
201

202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
#ifndef set_mask_bits
#define set_mask_bits(ptr, _mask, _bits)	\
({								\
	const typeof(*ptr) mask = (_mask), bits = (_bits);	\
	typeof(*ptr) old, new;					\
								\
	do {							\
		old = ACCESS_ONCE(*ptr);			\
		new = (old & ~mask) | bits;			\
	} while (cmpxchg(ptr, old, new) != old);		\
								\
	new;							\
})
#endif

217
#ifndef find_last_bit
R
Rusty Russell 已提交
218 219 220
/**
 * find_last_bit - find the last set bit in a memory region
 * @addr: The address to start the search at
221
 * @size: The number of bits to search
R
Rusty Russell 已提交
222
 *
223
 * Returns the bit number of the last set bit, or size.
R
Rusty Russell 已提交
224 225 226
 */
extern unsigned long find_last_bit(const unsigned long *addr,
				   unsigned long size);
227
#endif
R
Rusty Russell 已提交
228

229
#endif /* __KERNEL__ */
L
Linus Torvalds 已提交
230
#endif
反馈
建议
客服 返回
顶部