1
2
3
4
5
6
7
8
9
10
11
12#ifndef BITOPS_H
13#define BITOPS_H
14
15#include "qemu-common.h"
16
17#define BITS_PER_BYTE CHAR_BIT
18#define BITS_PER_LONG (sizeof (unsigned long) * BITS_PER_BYTE)
19
20#define BIT(nr) (1UL << (nr))
21#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
22#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
23#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
24
25
26
27
28
29
30
31static unsigned long bitops_ffsl(unsigned long word)
32{
33 int num = 0;
34
35#if LONG_MAX > 0x7FFFFFFF
36 if ((word & 0xffffffff) == 0) {
37 num += 32;
38 word >>= 32;
39 }
40#endif
41 if ((word & 0xffff) == 0) {
42 num += 16;
43 word >>= 16;
44 }
45 if ((word & 0xff) == 0) {
46 num += 8;
47 word >>= 8;
48 }
49 if ((word & 0xf) == 0) {
50 num += 4;
51 word >>= 4;
52 }
53 if ((word & 0x3) == 0) {
54 num += 2;
55 word >>= 2;
56 }
57 if ((word & 0x1) == 0) {
58 num += 1;
59 }
60 return num;
61}
62
63
64
65
66
67
68
69static inline unsigned long bitops_flsl(unsigned long word)
70{
71 int num = BITS_PER_LONG - 1;
72
73#if LONG_MAX > 0x7FFFFFFF
74 if (!(word & (~0ul << 32))) {
75 num -= 32;
76 word <<= 32;
77 }
78#endif
79 if (!(word & (~0ul << (BITS_PER_LONG-16)))) {
80 num -= 16;
81 word <<= 16;
82 }
83 if (!(word & (~0ul << (BITS_PER_LONG-8)))) {
84 num -= 8;
85 word <<= 8;
86 }
87 if (!(word & (~0ul << (BITS_PER_LONG-4)))) {
88 num -= 4;
89 word <<= 4;
90 }
91 if (!(word & (~0ul << (BITS_PER_LONG-2)))) {
92 num -= 2;
93
94 word <<= 2;
95 }
96 if (!(word & (~0ul << (BITS_PER_LONG-1))))
97 num -= 1;
98 return num;
99}
100
101
102
103
104
105
106
107static inline unsigned long ffz(unsigned long word)
108{
109 return bitops_ffsl(~word);
110}
111
112
113
114
115
116
117static inline void set_bit(int nr, unsigned long *addr)
118{
119 unsigned long mask = BIT_MASK(nr);
120 unsigned long *p = addr + BIT_WORD(nr);
121
122 *p |= mask;
123}
124
125
126
127
128
129
130static inline void clear_bit(int nr, unsigned long *addr)
131{
132 unsigned long mask = BIT_MASK(nr);
133 unsigned long *p = addr + BIT_WORD(nr);
134
135 *p &= ~mask;
136}
137
138
139
140
141
142
143static inline void change_bit(int nr, unsigned long *addr)
144{
145 unsigned long mask = BIT_MASK(nr);
146 unsigned long *p = addr + BIT_WORD(nr);
147
148 *p ^= mask;
149}
150
151
152
153
154
155
156static inline int test_and_set_bit(int nr, unsigned long *addr)
157{
158 unsigned long mask = BIT_MASK(nr);
159 unsigned long *p = addr + BIT_WORD(nr);
160 unsigned long old = *p;
161
162 *p = old | mask;
163 return (old & mask) != 0;
164}
165
166
167
168
169
170
171static inline int test_and_clear_bit(int nr, unsigned long *addr)
172{
173 unsigned long mask = BIT_MASK(nr);
174 unsigned long *p = addr + BIT_WORD(nr);
175 unsigned long old = *p;
176
177 *p = old & ~mask;
178 return (old & mask) != 0;
179}
180
181
182
183
184
185
186static inline int test_and_change_bit(int nr, unsigned long *addr)
187{
188 unsigned long mask = BIT_MASK(nr);
189 unsigned long *p = addr + BIT_WORD(nr);
190 unsigned long old = *p;
191
192 *p = old ^ mask;
193 return (old & mask) != 0;
194}
195
196
197
198
199
200
201static inline int test_bit(int nr, const unsigned long *addr)
202{
203 return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
204}
205
206
207
208
209
210
211
212
213unsigned long find_last_bit(const unsigned long *addr,
214 unsigned long size);
215
216
217
218
219
220
221
222unsigned long find_next_bit(const unsigned long *addr,
223 unsigned long size, unsigned long offset);
224
225
226
227
228
229
230
231
232unsigned long find_next_zero_bit(const unsigned long *addr,
233 unsigned long size,
234 unsigned long offset);
235
236
237
238
239
240
241
242
243static inline unsigned long find_first_bit(const unsigned long *addr,
244 unsigned long size)
245{
246 return find_next_bit(addr, size, 0);
247}
248
249
250
251
252
253
254
255
256static inline unsigned long find_first_zero_bit(const unsigned long *addr,
257 unsigned long size)
258{
259 return find_next_zero_bit(addr, size, 0);
260}
261
262static inline unsigned long hweight_long(unsigned long w)
263{
264 unsigned long count;
265
266 for (count = 0; w; w >>= 1) {
267 count += w & 1;
268 }
269 return count;
270}
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285static inline uint32_t extract32(uint32_t value, int start, int length)
286{
287 assert(start >= 0 && length > 0 && length <= 32 - start);
288 return (value >> start) & (~0U >> (32 - length));
289}
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304static inline uint64_t extract64(uint64_t value, int start, int length)
305{
306 assert(start >= 0 && length > 0 && length <= 64 - start);
307 return (value >> start) & (~0ULL >> (64 - length));
308}
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327static inline uint32_t deposit32(uint32_t value, int start, int length,
328 uint32_t fieldval)
329{
330 uint32_t mask;
331 assert(start >= 0 && length > 0 && length <= 32 - start);
332 mask = (~0U >> (32 - length)) << start;
333 return (value & ~mask) | ((fieldval << start) & mask);
334}
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353static inline uint64_t deposit64(uint64_t value, int start, int length,
354 uint64_t fieldval)
355{
356 uint64_t mask;
357 assert(start >= 0 && length > 0 && length <= 64 - start);
358 mask = (~0ULL >> (64 - length)) << start;
359 return (value & ~mask) | ((fieldval << start) & mask);
360}
361
362#endif
363