]> Git Repo - qemu.git/blob - include/qemu/bitops.h
bitops: Write bitops_flsl in terms of clzl
[qemu.git] / include / qemu / bitops.h
1 /*
2  * Bitops Module
3  *
4  * Copyright (C) 2010 Corentin Chary <[email protected]>
5  *
6  * Mostly inspired by (stolen from) linux/bitmap.h and linux/bitops.h
7  *
8  * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
9  * See the COPYING.LIB file in the top-level directory.
10  */
11
12 #ifndef BITOPS_H
13 #define BITOPS_H
14
15 #include "qemu-common.h"
16 #include "host-utils.h"
17
18 #define BITS_PER_BYTE           CHAR_BIT
19 #define BITS_PER_LONG           (sizeof (unsigned long) * BITS_PER_BYTE)
20
21 #define BIT(nr)                 (1UL << (nr))
22 #define BIT_MASK(nr)            (1UL << ((nr) % BITS_PER_LONG))
23 #define BIT_WORD(nr)            ((nr) / BITS_PER_LONG)
24 #define BITS_TO_LONGS(nr)       DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
25
26 /**
27  * bitops_ctzl - count trailing zeroes in word.
28  * @word: The word to search
29  *
30  * Returns -1 if no bit exists.  Note that compared to the C library
31  * routine ffsl, this one returns one less.
32  */
33 static unsigned long bitops_ctzl(unsigned long word)
34 {
35 #if QEMU_GNUC_PREREQ(3, 4)
36     return __builtin_ffsl(word) - 1;
37 #else
38     if (!word) {
39         return -1;
40     }
41
42     if (sizeof(long) == 4) {
43         return ctz32(word);
44     } else if (sizeof(long) == 8) {
45         return ctz64(word);
46     } else {
47         abort();
48     }
49 #endif
50 }
51
52 /**
53  * bitops_fls - find last (most-significant) set bit in a long word
54  * @word: the word to search
55  *
56  * Undefined if no set bit exists, so code should check against 0 first.
57  */
58 static inline unsigned long bitops_flsl(unsigned long word)
59 {
60     return BITS_PER_LONG - 1 - clzl(word);
61 }
62
63 /**
64  * cto - count trailing ones in word.
65  * @word: The word to search
66  *
67  * Returns -1 if all bit are set.
68  */
69 static inline unsigned long bitops_ctol(unsigned long word)
70 {
71     return bitops_ctzl(~word);
72 }
73
74 /**
75  * set_bit - Set a bit in memory
76  * @nr: the bit to set
77  * @addr: the address to start counting from
78  */
79 static inline void set_bit(int nr, unsigned long *addr)
80 {
81         unsigned long mask = BIT_MASK(nr);
82         unsigned long *p = addr + BIT_WORD(nr);
83
84         *p  |= mask;
85 }
86
87 /**
88  * clear_bit - Clears a bit in memory
89  * @nr: Bit to clear
90  * @addr: Address to start counting from
91  */
92 static inline void clear_bit(int nr, unsigned long *addr)
93 {
94         unsigned long mask = BIT_MASK(nr);
95         unsigned long *p = addr + BIT_WORD(nr);
96
97         *p &= ~mask;
98 }
99
100 /**
101  * change_bit - Toggle a bit in memory
102  * @nr: Bit to change
103  * @addr: Address to start counting from
104  */
105 static inline void change_bit(int nr, unsigned long *addr)
106 {
107         unsigned long mask = BIT_MASK(nr);
108         unsigned long *p = addr + BIT_WORD(nr);
109
110         *p ^= mask;
111 }
112
113 /**
114  * test_and_set_bit - Set a bit and return its old value
115  * @nr: Bit to set
116  * @addr: Address to count from
117  */
118 static inline int test_and_set_bit(int nr, unsigned long *addr)
119 {
120         unsigned long mask = BIT_MASK(nr);
121         unsigned long *p = addr + BIT_WORD(nr);
122         unsigned long old = *p;
123
124         *p = old | mask;
125         return (old & mask) != 0;
126 }
127
128 /**
129  * test_and_clear_bit - Clear a bit and return its old value
130  * @nr: Bit to clear
131  * @addr: Address to count from
132  */
133 static inline int test_and_clear_bit(int nr, unsigned long *addr)
134 {
135         unsigned long mask = BIT_MASK(nr);
136         unsigned long *p = addr + BIT_WORD(nr);
137         unsigned long old = *p;
138
139         *p = old & ~mask;
140         return (old & mask) != 0;
141 }
142
143 /**
144  * test_and_change_bit - Change a bit and return its old value
145  * @nr: Bit to change
146  * @addr: Address to count from
147  */
148 static inline int test_and_change_bit(int nr, unsigned long *addr)
149 {
150         unsigned long mask = BIT_MASK(nr);
151         unsigned long *p = addr + BIT_WORD(nr);
152         unsigned long old = *p;
153
154         *p = old ^ mask;
155         return (old & mask) != 0;
156 }
157
158 /**
159  * test_bit - Determine whether a bit is set
160  * @nr: bit number to test
161  * @addr: Address to start counting from
162  */
163 static inline int test_bit(int nr, const unsigned long *addr)
164 {
165         return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
166 }
167
168 /**
169  * find_last_bit - find the last set bit in a memory region
170  * @addr: The address to start the search at
171  * @size: The maximum size to search
172  *
173  * Returns the bit number of the first set bit, or size.
174  */
175 unsigned long find_last_bit(const unsigned long *addr,
176                             unsigned long size);
177
178 /**
179  * find_next_bit - find the next set bit in a memory region
180  * @addr: The address to base the search on
181  * @offset: The bitnumber to start searching at
182  * @size: The bitmap size in bits
183  */
184 unsigned long find_next_bit(const unsigned long *addr,
185                                    unsigned long size, unsigned long offset);
186
187 /**
188  * find_next_zero_bit - find the next cleared bit in a memory region
189  * @addr: The address to base the search on
190  * @offset: The bitnumber to start searching at
191  * @size: The bitmap size in bits
192  */
193
194 unsigned long find_next_zero_bit(const unsigned long *addr,
195                                  unsigned long size,
196                                  unsigned long offset);
197
198 /**
199  * find_first_bit - find the first set bit in a memory region
200  * @addr: The address to start the search at
201  * @size: The maximum size to search
202  *
203  * Returns the bit number of the first set bit.
204  */
205 static inline unsigned long find_first_bit(const unsigned long *addr,
206                                            unsigned long size)
207 {
208     return find_next_bit(addr, size, 0);
209 }
210
211 /**
212  * find_first_zero_bit - find the first cleared bit in a memory region
213  * @addr: The address to start the search at
214  * @size: The maximum size to search
215  *
216  * Returns the bit number of the first cleared bit.
217  */
218 static inline unsigned long find_first_zero_bit(const unsigned long *addr,
219                                                 unsigned long size)
220 {
221     return find_next_zero_bit(addr, size, 0);
222 }
223
224 static inline unsigned long hweight_long(unsigned long w)
225 {
226     unsigned long count;
227
228     for (count = 0; w; w >>= 1) {
229         count += w & 1;
230     }
231     return count;
232 }
233
234 /**
235  * extract32:
236  * @value: the value to extract the bit field from
237  * @start: the lowest bit in the bit field (numbered from 0)
238  * @length: the length of the bit field
239  *
240  * Extract from the 32 bit input @value the bit field specified by the
241  * @start and @length parameters, and return it. The bit field must
242  * lie entirely within the 32 bit word. It is valid to request that
243  * all 32 bits are returned (ie @length 32 and @start 0).
244  *
245  * Returns: the value of the bit field extracted from the input value.
246  */
247 static inline uint32_t extract32(uint32_t value, int start, int length)
248 {
249     assert(start >= 0 && length > 0 && length <= 32 - start);
250     return (value >> start) & (~0U >> (32 - length));
251 }
252
253 /**
254  * extract64:
255  * @value: the value to extract the bit field from
256  * @start: the lowest bit in the bit field (numbered from 0)
257  * @length: the length of the bit field
258  *
259  * Extract from the 64 bit input @value the bit field specified by the
260  * @start and @length parameters, and return it. The bit field must
261  * lie entirely within the 64 bit word. It is valid to request that
262  * all 64 bits are returned (ie @length 64 and @start 0).
263  *
264  * Returns: the value of the bit field extracted from the input value.
265  */
266 static inline uint64_t extract64(uint64_t value, int start, int length)
267 {
268     assert(start >= 0 && length > 0 && length <= 64 - start);
269     return (value >> start) & (~0ULL >> (64 - length));
270 }
271
272 /**
273  * deposit32:
274  * @value: initial value to insert bit field into
275  * @start: the lowest bit in the bit field (numbered from 0)
276  * @length: the length of the bit field
277  * @fieldval: the value to insert into the bit field
278  *
279  * Deposit @fieldval into the 32 bit @value at the bit field specified
280  * by the @start and @length parameters, and return the modified
281  * @value. Bits of @value outside the bit field are not modified.
282  * Bits of @fieldval above the least significant @length bits are
283  * ignored. The bit field must lie entirely within the 32 bit word.
284  * It is valid to request that all 32 bits are modified (ie @length
285  * 32 and @start 0).
286  *
287  * Returns: the modified @value.
288  */
289 static inline uint32_t deposit32(uint32_t value, int start, int length,
290                                  uint32_t fieldval)
291 {
292     uint32_t mask;
293     assert(start >= 0 && length > 0 && length <= 32 - start);
294     mask = (~0U >> (32 - length)) << start;
295     return (value & ~mask) | ((fieldval << start) & mask);
296 }
297
298 /**
299  * deposit64:
300  * @value: initial value to insert bit field into
301  * @start: the lowest bit in the bit field (numbered from 0)
302  * @length: the length of the bit field
303  * @fieldval: the value to insert into the bit field
304  *
305  * Deposit @fieldval into the 64 bit @value at the bit field specified
306  * by the @start and @length parameters, and return the modified
307  * @value. Bits of @value outside the bit field are not modified.
308  * Bits of @fieldval above the least significant @length bits are
309  * ignored. The bit field must lie entirely within the 64 bit word.
310  * It is valid to request that all 64 bits are modified (ie @length
311  * 64 and @start 0).
312  *
313  * Returns: the modified @value.
314  */
315 static inline uint64_t deposit64(uint64_t value, int start, int length,
316                                  uint64_t fieldval)
317 {
318     uint64_t mask;
319     assert(start >= 0 && length > 0 && length <= 64 - start);
320     mask = (~0ULL >> (64 - length)) << start;
321     return (value & ~mask) | ((fieldval << start) & mask);
322 }
323
324 #endif
This page took 0.040777 seconds and 4 git commands to generate.