hw/i2c: add asynchronous send
[qemu.git] / include / qemu / int128.h
blobd2b76ca6acdcc45eddf0f0ba75ddb22af8595fe5
1 #ifndef INT128_H
2 #define INT128_H
4 #include "qemu/bswap.h"
6 #ifdef CONFIG_INT128
7 typedef __int128_t Int128;
9 static inline Int128 int128_make64(uint64_t a)
11 return a;
14 static inline Int128 int128_makes64(int64_t a)
16 return a;
19 static inline Int128 int128_make128(uint64_t lo, uint64_t hi)
21 return (__uint128_t)hi << 64 | lo;
24 static inline uint64_t int128_get64(Int128 a)
26 uint64_t r = a;
27 assert(r == a);
28 return r;
31 static inline uint64_t int128_getlo(Int128 a)
33 return a;
36 static inline int64_t int128_gethi(Int128 a)
38 return a >> 64;
41 static inline Int128 int128_zero(void)
43 return 0;
46 static inline Int128 int128_one(void)
48 return 1;
51 static inline Int128 int128_2_64(void)
53 return (Int128)1 << 64;
56 static inline Int128 int128_exts64(int64_t a)
58 return a;
61 static inline Int128 int128_not(Int128 a)
63 return ~a;
66 static inline Int128 int128_and(Int128 a, Int128 b)
68 return a & b;
71 static inline Int128 int128_or(Int128 a, Int128 b)
73 return a | b;
76 static inline Int128 int128_xor(Int128 a, Int128 b)
78 return a ^ b;
81 static inline Int128 int128_rshift(Int128 a, int n)
83 return a >> n;
86 static inline Int128 int128_urshift(Int128 a, int n)
88 return (__uint128_t)a >> n;
91 static inline Int128 int128_lshift(Int128 a, int n)
93 return a << n;
96 static inline Int128 int128_add(Int128 a, Int128 b)
98 return a + b;
101 static inline Int128 int128_neg(Int128 a)
103 return -a;
106 static inline Int128 int128_sub(Int128 a, Int128 b)
108 return a - b;
111 static inline bool int128_nonneg(Int128 a)
113 return a >= 0;
116 static inline bool int128_eq(Int128 a, Int128 b)
118 return a == b;
121 static inline bool int128_ne(Int128 a, Int128 b)
123 return a != b;
126 static inline bool int128_ge(Int128 a, Int128 b)
128 return a >= b;
131 static inline bool int128_uge(Int128 a, Int128 b)
133 return ((__uint128_t)a) >= ((__uint128_t)b);
136 static inline bool int128_lt(Int128 a, Int128 b)
138 return a < b;
141 static inline bool int128_ult(Int128 a, Int128 b)
143 return (__uint128_t)a < (__uint128_t)b;
146 static inline bool int128_le(Int128 a, Int128 b)
148 return a <= b;
151 static inline bool int128_gt(Int128 a, Int128 b)
153 return a > b;
156 static inline bool int128_nz(Int128 a)
158 return a != 0;
161 static inline Int128 int128_min(Int128 a, Int128 b)
163 return a < b ? a : b;
166 static inline Int128 int128_max(Int128 a, Int128 b)
168 return a > b ? a : b;
171 static inline void int128_addto(Int128 *a, Int128 b)
173 *a += b;
176 static inline void int128_subfrom(Int128 *a, Int128 b)
178 *a -= b;
181 static inline Int128 bswap128(Int128 a)
183 #if __has_builtin(__builtin_bswap128)
184 return __builtin_bswap128(a);
185 #else
186 return int128_make128(bswap64(int128_gethi(a)), bswap64(int128_getlo(a)));
187 #endif
190 static inline int clz128(Int128 a)
192 if (a >> 64) {
193 return __builtin_clzll(a >> 64);
194 } else {
195 return (a) ? __builtin_clzll((uint64_t)a) + 64 : 128;
199 static inline Int128 int128_divu(Int128 a, Int128 b)
201 return (__uint128_t)a / (__uint128_t)b;
204 static inline Int128 int128_remu(Int128 a, Int128 b)
206 return (__uint128_t)a % (__uint128_t)b;
209 static inline Int128 int128_divs(Int128 a, Int128 b)
211 return a / b;
214 static inline Int128 int128_rems(Int128 a, Int128 b)
216 return a % b;
219 #else /* !CONFIG_INT128 */
221 typedef struct Int128 Int128;
224 * We guarantee that the in-memory byte representation of an
225 * Int128 is that of a host-endian-order 128-bit integer
226 * (whether using this struct or the __int128_t version of the type).
227 * Some code using this type relies on this (eg when copying it into
228 * guest memory or a gdb protocol buffer, or by using Int128 in
229 * a union with other integer types).
231 struct Int128 {
232 #if HOST_BIG_ENDIAN
233 int64_t hi;
234 uint64_t lo;
235 #else
236 uint64_t lo;
237 int64_t hi;
238 #endif
241 static inline Int128 int128_make64(uint64_t a)
243 return (Int128) { .lo = a, .hi = 0 };
246 static inline Int128 int128_makes64(int64_t a)
248 return (Int128) { .lo = a, .hi = a >> 63 };
251 static inline Int128 int128_make128(uint64_t lo, uint64_t hi)
253 return (Int128) { .lo = lo, .hi = hi };
256 static inline uint64_t int128_get64(Int128 a)
258 assert(!a.hi);
259 return a.lo;
262 static inline uint64_t int128_getlo(Int128 a)
264 return a.lo;
267 static inline int64_t int128_gethi(Int128 a)
269 return a.hi;
272 static inline Int128 int128_zero(void)
274 return int128_make64(0);
277 static inline Int128 int128_one(void)
279 return int128_make64(1);
282 static inline Int128 int128_2_64(void)
284 return int128_make128(0, 1);
287 static inline Int128 int128_exts64(int64_t a)
289 return int128_make128(a, (a < 0) ? -1 : 0);
292 static inline Int128 int128_not(Int128 a)
294 return int128_make128(~a.lo, ~a.hi);
297 static inline Int128 int128_and(Int128 a, Int128 b)
299 return int128_make128(a.lo & b.lo, a.hi & b.hi);
302 static inline Int128 int128_or(Int128 a, Int128 b)
304 return int128_make128(a.lo | b.lo, a.hi | b.hi);
307 static inline Int128 int128_xor(Int128 a, Int128 b)
309 return int128_make128(a.lo ^ b.lo, a.hi ^ b.hi);
312 static inline Int128 int128_rshift(Int128 a, int n)
314 int64_t h;
315 if (!n) {
316 return a;
318 h = a.hi >> (n & 63);
319 if (n >= 64) {
320 return int128_make128(h, h >> 63);
321 } else {
322 return int128_make128((a.lo >> n) | ((uint64_t)a.hi << (64 - n)), h);
326 static inline Int128 int128_urshift(Int128 a, int n)
328 uint64_t h = a.hi;
329 if (!n) {
330 return a;
332 h = h >> (n & 63);
333 if (n >= 64) {
334 return int128_make64(h);
335 } else {
336 return int128_make128((a.lo >> n) | ((uint64_t)a.hi << (64 - n)), h);
340 static inline Int128 int128_lshift(Int128 a, int n)
342 uint64_t l = a.lo << (n & 63);
343 if (n >= 64) {
344 return int128_make128(0, l);
345 } else if (n > 0) {
346 return int128_make128(l, (a.hi << n) | (a.lo >> (64 - n)));
348 return a;
351 static inline Int128 int128_add(Int128 a, Int128 b)
353 uint64_t lo = a.lo + b.lo;
355 /* a.lo <= a.lo + b.lo < a.lo + k (k is the base, 2^64). Hence,
356 * a.lo + b.lo >= k implies 0 <= lo = a.lo + b.lo - k < a.lo.
357 * Similarly, a.lo + b.lo < k implies a.lo <= lo = a.lo + b.lo < k.
359 * So the carry is lo < a.lo.
361 return int128_make128(lo, (uint64_t)a.hi + b.hi + (lo < a.lo));
364 static inline Int128 int128_neg(Int128 a)
366 uint64_t lo = -a.lo;
367 return int128_make128(lo, ~(uint64_t)a.hi + !lo);
370 static inline Int128 int128_sub(Int128 a, Int128 b)
372 return int128_make128(a.lo - b.lo, (uint64_t)a.hi - b.hi - (a.lo < b.lo));
375 static inline bool int128_nonneg(Int128 a)
377 return a.hi >= 0;
380 static inline bool int128_eq(Int128 a, Int128 b)
382 return a.lo == b.lo && a.hi == b.hi;
385 static inline bool int128_ne(Int128 a, Int128 b)
387 return !int128_eq(a, b);
390 static inline bool int128_ge(Int128 a, Int128 b)
392 return a.hi > b.hi || (a.hi == b.hi && a.lo >= b.lo);
395 static inline bool int128_uge(Int128 a, Int128 b)
397 return (uint64_t)a.hi > (uint64_t)b.hi || (a.hi == b.hi && a.lo >= b.lo);
400 static inline bool int128_lt(Int128 a, Int128 b)
402 return !int128_ge(a, b);
405 static inline bool int128_ult(Int128 a, Int128 b)
407 return !int128_uge(a, b);
410 static inline bool int128_le(Int128 a, Int128 b)
412 return int128_ge(b, a);
415 static inline bool int128_gt(Int128 a, Int128 b)
417 return !int128_le(a, b);
420 static inline bool int128_nz(Int128 a)
422 return a.lo || a.hi;
425 static inline Int128 int128_min(Int128 a, Int128 b)
427 return int128_le(a, b) ? a : b;
430 static inline Int128 int128_max(Int128 a, Int128 b)
432 return int128_ge(a, b) ? a : b;
435 static inline void int128_addto(Int128 *a, Int128 b)
437 *a = int128_add(*a, b);
440 static inline void int128_subfrom(Int128 *a, Int128 b)
442 *a = int128_sub(*a, b);
445 static inline Int128 bswap128(Int128 a)
447 return int128_make128(bswap64(a.hi), bswap64(a.lo));
450 static inline int clz128(Int128 a)
452 if (a.hi) {
453 return __builtin_clzll(a.hi);
454 } else {
455 return (a.lo) ? __builtin_clzll(a.lo) + 64 : 128;
459 Int128 int128_divu(Int128, Int128);
460 Int128 int128_remu(Int128, Int128);
461 Int128 int128_divs(Int128, Int128);
462 Int128 int128_rems(Int128, Int128);
464 #endif /* CONFIG_INT128 */
466 static inline void bswap128s(Int128 *s)
468 *s = bswap128(*s);
471 #define UINT128_MAX int128_make128(~0LL, ~0LL)
472 #define INT128_MAX int128_make128(UINT64_MAX, INT64_MAX)
473 #define INT128_MIN int128_make128(0, INT64_MIN)
475 #endif /* INT128_H */