1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26#ifndef HOST_UTILS_H
27#define HOST_UTILS_H
28
29#include "qemu/bswap.h"
30
31#ifdef CONFIG_INT128
32static inline void mulu64(uint64_t *plow, uint64_t *phigh,
33 uint64_t a, uint64_t b)
34{
35 __uint128_t r = (__uint128_t)a * b;
36 *plow = r;
37 *phigh = r >> 64;
38}
39
40static inline void muls64(uint64_t *plow, uint64_t *phigh,
41 int64_t a, int64_t b)
42{
43 __int128_t r = (__int128_t)a * b;
44 *plow = r;
45 *phigh = r >> 64;
46}
47
48
49static inline uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
50{
51 return (__int128_t)a * b / c;
52}
53
54static inline int divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor)
55{
56 if (divisor == 0) {
57 return 1;
58 } else {
59 __uint128_t dividend = ((__uint128_t)*phigh << 64) | *plow;
60 __uint128_t result = dividend / divisor;
61 *plow = result;
62 *phigh = dividend % divisor;
63 return result > UINT64_MAX;
64 }
65}
66
67static inline int divs128(int64_t *plow, int64_t *phigh, int64_t divisor)
68{
69 if (divisor == 0) {
70 return 1;
71 } else {
72 __int128_t dividend = ((__int128_t)*phigh << 64) | *plow;
73 __int128_t result = dividend / divisor;
74 *plow = result;
75 *phigh = dividend % divisor;
76 return result != *plow;
77 }
78}
79#else
80void muls64(uint64_t *phigh, uint64_t *plow, int64_t a, int64_t b);
81void mulu64(uint64_t *phigh, uint64_t *plow, uint64_t a, uint64_t b);
82int divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor);
83int divs128(int64_t *plow, int64_t *phigh, int64_t divisor);
84
85static inline uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
86{
87 union {
88 uint64_t ll;
89 struct {
90#ifdef HOST_WORDS_BIGENDIAN
91 uint32_t high, low;
92#else
93 uint32_t low, high;
94#endif
95 } l;
96 } u, res;
97 uint64_t rl, rh;
98
99 u.ll = a;
100 rl = (uint64_t)u.l.low * (uint64_t)b;
101 rh = (uint64_t)u.l.high * (uint64_t)b;
102 rh += (rl >> 32);
103 res.l.high = rh / c;
104 res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
105 return res.ll;
106}
107#endif
108
109
110
111
112
113
114
115
116static inline int clz32(uint32_t val)
117{
118#if QEMU_GNUC_PREREQ(3, 4)
119 return val ? __builtin_clz(val) : 32;
120#else
121
122 int cnt = 0;
123
124 if (!(val & 0xFFFF0000U)) {
125 cnt += 16;
126 val <<= 16;
127 }
128 if (!(val & 0xFF000000U)) {
129 cnt += 8;
130 val <<= 8;
131 }
132 if (!(val & 0xF0000000U)) {
133 cnt += 4;
134 val <<= 4;
135 }
136 if (!(val & 0xC0000000U)) {
137 cnt += 2;
138 val <<= 2;
139 }
140 if (!(val & 0x80000000U)) {
141 cnt++;
142 val <<= 1;
143 }
144 if (!(val & 0x80000000U)) {
145 cnt++;
146 }
147 return cnt;
148#endif
149}
150
151
152
153
154
155
156
157static inline int clo32(uint32_t val)
158{
159 return clz32(~val);
160}
161
162
163
164
165
166
167
168
169static inline int clz64(uint64_t val)
170{
171#if QEMU_GNUC_PREREQ(3, 4)
172 return val ? __builtin_clzll(val) : 64;
173#else
174 int cnt = 0;
175
176 if (!(val >> 32)) {
177 cnt += 32;
178 } else {
179 val >>= 32;
180 }
181
182 return cnt + clz32(val);
183#endif
184}
185
186
187
188
189
190
191
192static inline int clo64(uint64_t val)
193{
194 return clz64(~val);
195}
196
197
198
199
200
201
202
203
204static inline int ctz32(uint32_t val)
205{
206#if QEMU_GNUC_PREREQ(3, 4)
207 return val ? __builtin_ctz(val) : 32;
208#else
209
210 int cnt;
211
212 cnt = 0;
213 if (!(val & 0x0000FFFFUL)) {
214 cnt += 16;
215 val >>= 16;
216 }
217 if (!(val & 0x000000FFUL)) {
218 cnt += 8;
219 val >>= 8;
220 }
221 if (!(val & 0x0000000FUL)) {
222 cnt += 4;
223 val >>= 4;
224 }
225 if (!(val & 0x00000003UL)) {
226 cnt += 2;
227 val >>= 2;
228 }
229 if (!(val & 0x00000001UL)) {
230 cnt++;
231 val >>= 1;
232 }
233 if (!(val & 0x00000001UL)) {
234 cnt++;
235 }
236
237 return cnt;
238#endif
239}
240
241
242
243
244
245
246
247static inline int cto32(uint32_t val)
248{
249 return ctz32(~val);
250}
251
252
253
254
255
256
257
258
259static inline int ctz64(uint64_t val)
260{
261#if QEMU_GNUC_PREREQ(3, 4)
262 return val ? __builtin_ctzll(val) : 64;
263#else
264 int cnt;
265
266 cnt = 0;
267 if (!((uint32_t)val)) {
268 cnt += 32;
269 val >>= 32;
270 }
271
272 return cnt + ctz32(val);
273#endif
274}
275
276
277
278
279
280
281
282static inline int cto64(uint64_t val)
283{
284 return ctz64(~val);
285}
286
287
288
289
290
291
292
293
294static inline int clrsb32(uint32_t val)
295{
296#if QEMU_GNUC_PREREQ(4, 7)
297 return __builtin_clrsb(val);
298#else
299 return clz32(val ^ ((int32_t)val >> 1)) - 1;
300#endif
301}
302
303
304
305
306
307
308
309
310static inline int clrsb64(uint64_t val)
311{
312#if QEMU_GNUC_PREREQ(4, 7)
313 return __builtin_clrsbll(val);
314#else
315 return clz64(val ^ ((int64_t)val >> 1)) - 1;
316#endif
317}
318
319
320
321
322
323static inline int ctpop8(uint8_t val)
324{
325#if QEMU_GNUC_PREREQ(3, 4)
326 return __builtin_popcount(val);
327#else
328 val = (val & 0x55) + ((val >> 1) & 0x55);
329 val = (val & 0x33) + ((val >> 2) & 0x33);
330 val = (val & 0x0f) + ((val >> 4) & 0x0f);
331
332 return val;
333#endif
334}
335
336
337
338
339
340static inline int ctpop16(uint16_t val)
341{
342#if QEMU_GNUC_PREREQ(3, 4)
343 return __builtin_popcount(val);
344#else
345 val = (val & 0x5555) + ((val >> 1) & 0x5555);
346 val = (val & 0x3333) + ((val >> 2) & 0x3333);
347 val = (val & 0x0f0f) + ((val >> 4) & 0x0f0f);
348 val = (val & 0x00ff) + ((val >> 8) & 0x00ff);
349
350 return val;
351#endif
352}
353
354
355
356
357
358static inline int ctpop32(uint32_t val)
359{
360#if QEMU_GNUC_PREREQ(3, 4)
361 return __builtin_popcount(val);
362#else
363 val = (val & 0x55555555) + ((val >> 1) & 0x55555555);
364 val = (val & 0x33333333) + ((val >> 2) & 0x33333333);
365 val = (val & 0x0f0f0f0f) + ((val >> 4) & 0x0f0f0f0f);
366 val = (val & 0x00ff00ff) + ((val >> 8) & 0x00ff00ff);
367 val = (val & 0x0000ffff) + ((val >> 16) & 0x0000ffff);
368
369 return val;
370#endif
371}
372
373
374
375
376
377static inline int ctpop64(uint64_t val)
378{
379#if QEMU_GNUC_PREREQ(3, 4)
380 return __builtin_popcountll(val);
381#else
382 val = (val & 0x5555555555555555ULL) + ((val >> 1) & 0x5555555555555555ULL);
383 val = (val & 0x3333333333333333ULL) + ((val >> 2) & 0x3333333333333333ULL);
384 val = (val & 0x0f0f0f0f0f0f0f0fULL) + ((val >> 4) & 0x0f0f0f0f0f0f0f0fULL);
385 val = (val & 0x00ff00ff00ff00ffULL) + ((val >> 8) & 0x00ff00ff00ff00ffULL);
386 val = (val & 0x0000ffff0000ffffULL) + ((val >> 16) & 0x0000ffff0000ffffULL);
387 val = (val & 0x00000000ffffffffULL) + ((val >> 32) & 0x00000000ffffffffULL);
388
389 return val;
390#endif
391}
392
393
394
395
396
397static inline uint8_t revbit8(uint8_t x)
398{
399
400 x = ((x & 0xf0) >> 4)
401 | ((x & 0x0f) << 4);
402
403 x = ((x & 0x88) >> 3)
404 | ((x & 0x44) >> 1)
405 | ((x & 0x22) << 1)
406 | ((x & 0x11) << 3);
407 return x;
408}
409
410
411
412
413
414static inline uint16_t revbit16(uint16_t x)
415{
416
417 x = bswap16(x);
418
419 x = ((x & 0xf0f0) >> 4)
420 | ((x & 0x0f0f) << 4);
421
422 x = ((x & 0x8888) >> 3)
423 | ((x & 0x4444) >> 1)
424 | ((x & 0x2222) << 1)
425 | ((x & 0x1111) << 3);
426 return x;
427}
428
429
430
431
432
433static inline uint32_t revbit32(uint32_t x)
434{
435
436 x = bswap32(x);
437
438 x = ((x & 0xf0f0f0f0u) >> 4)
439 | ((x & 0x0f0f0f0fu) << 4);
440
441 x = ((x & 0x88888888u) >> 3)
442 | ((x & 0x44444444u) >> 1)
443 | ((x & 0x22222222u) << 1)
444 | ((x & 0x11111111u) << 3);
445 return x;
446}
447
448
449
450
451
452static inline uint64_t revbit64(uint64_t x)
453{
454
455 x = bswap64(x);
456
457 x = ((x & 0xf0f0f0f0f0f0f0f0ull) >> 4)
458 | ((x & 0x0f0f0f0f0f0f0f0full) << 4);
459
460 x = ((x & 0x8888888888888888ull) >> 3)
461 | ((x & 0x4444444444444444ull) >> 1)
462 | ((x & 0x2222222222222222ull) << 1)
463 | ((x & 0x1111111111111111ull) << 3);
464 return x;
465}
466
467
468
469#if ULONG_MAX == UINT32_MAX
470# define clzl clz32
471# define ctzl ctz32
472# define clol clo32
473# define ctol cto32
474# define ctpopl ctpop32
475# define revbitl revbit32
476#elif ULONG_MAX == UINT64_MAX
477# define clzl clz64
478# define ctzl ctz64
479# define clol clo64
480# define ctol cto64
481# define ctpopl ctpop64
482# define revbitl revbit64
483#else
484# error Unknown sizeof long
485#endif
486
487static inline bool is_power_of_2(uint64_t value)
488{
489 if (!value) {
490 return false;
491 }
492
493 return !(value & (value - 1));
494}
495
496
497static inline int64_t pow2floor(int64_t value)
498{
499 if (!is_power_of_2(value)) {
500 value = 0x8000000000000000ULL >> clz64(value);
501 }
502 return value;
503}
504
505
506static inline uint64_t pow2ceil(uint64_t value)
507{
508 uint8_t nlz = clz64(value);
509
510 if (is_power_of_2(value)) {
511 return value;
512 }
513 if (!nlz) {
514 return 0;
515 }
516 return 1ULL << (64 - nlz);
517}
518
519#endif
520