]>
git.proxmox.com Git - mirror_qemu.git/blob - include/qemu/int128.h
4 #include "qemu/bswap.h"
7 * With TCI, we need to use libffi for interfacing with TCG helpers.
8 * But libffi does not support __int128_t, and therefore cannot pass
9 * or return values of this type, force use of the Int128 struct.
11 #if defined(CONFIG_INT128) && !defined(CONFIG_TCG_INTERPRETER)
12 typedef __int128_t Int128
;
13 typedef __int128_t
__attribute__((aligned(16))) Int128Aligned
;
15 static inline Int128
int128_make64(uint64_t a
)
20 static inline Int128
int128_makes64(int64_t a
)
25 static inline Int128
int128_make128(uint64_t lo
, uint64_t hi
)
27 return (__uint128_t
)hi
<< 64 | lo
;
30 static inline uint64_t int128_get64(Int128 a
)
37 static inline uint64_t int128_getlo(Int128 a
)
42 static inline int64_t int128_gethi(Int128 a
)
47 static inline Int128
int128_zero(void)
52 static inline Int128
int128_one(void)
57 static inline Int128
int128_2_64(void)
59 return (Int128
)1 << 64;
62 static inline Int128
int128_exts64(int64_t a
)
67 static inline Int128
int128_not(Int128 a
)
72 static inline Int128
int128_and(Int128 a
, Int128 b
)
77 static inline Int128
int128_or(Int128 a
, Int128 b
)
82 static inline Int128
int128_xor(Int128 a
, Int128 b
)
87 static inline Int128
int128_rshift(Int128 a
, int n
)
92 static inline Int128
int128_urshift(Int128 a
, int n
)
94 return (__uint128_t
)a
>> n
;
97 static inline Int128
int128_lshift(Int128 a
, int n
)
102 static inline Int128
int128_add(Int128 a
, Int128 b
)
107 static inline Int128
int128_neg(Int128 a
)
112 static inline Int128
int128_sub(Int128 a
, Int128 b
)
117 static inline bool int128_nonneg(Int128 a
)
122 static inline bool int128_eq(Int128 a
, Int128 b
)
127 static inline bool int128_ne(Int128 a
, Int128 b
)
132 static inline bool int128_ge(Int128 a
, Int128 b
)
137 static inline bool int128_uge(Int128 a
, Int128 b
)
139 return ((__uint128_t
)a
) >= ((__uint128_t
)b
);
142 static inline bool int128_lt(Int128 a
, Int128 b
)
147 static inline bool int128_ult(Int128 a
, Int128 b
)
149 return (__uint128_t
)a
< (__uint128_t
)b
;
152 static inline bool int128_le(Int128 a
, Int128 b
)
157 static inline bool int128_gt(Int128 a
, Int128 b
)
162 static inline bool int128_nz(Int128 a
)
167 static inline Int128
int128_min(Int128 a
, Int128 b
)
169 return a
< b
? a
: b
;
172 static inline Int128
int128_max(Int128 a
, Int128 b
)
174 return a
> b
? a
: b
;
177 static inline void int128_addto(Int128
*a
, Int128 b
)
182 static inline void int128_subfrom(Int128
*a
, Int128 b
)
187 static inline Int128
bswap128(Int128 a
)
189 #if __has_builtin(__builtin_bswap128)
190 return __builtin_bswap128(a
);
192 return int128_make128(bswap64(int128_gethi(a
)), bswap64(int128_getlo(a
)));
196 static inline int clz128(Int128 a
)
199 return __builtin_clzll(a
>> 64);
201 return (a
) ? __builtin_clzll((uint64_t)a
) + 64 : 128;
205 static inline Int128
int128_divu(Int128 a
, Int128 b
)
207 return (__uint128_t
)a
/ (__uint128_t
)b
;
210 static inline Int128
int128_remu(Int128 a
, Int128 b
)
212 return (__uint128_t
)a
% (__uint128_t
)b
;
215 static inline Int128
int128_divs(Int128 a
, Int128 b
)
220 static inline Int128
int128_rems(Int128 a
, Int128 b
)
225 #else /* !CONFIG_INT128 */
227 typedef struct Int128 Int128
;
228 typedef struct Int128
__attribute__((aligned(16))) Int128Aligned
;
231 * We guarantee that the in-memory byte representation of an
232 * Int128 is that of a host-endian-order 128-bit integer
233 * (whether using this struct or the __int128_t version of the type).
234 * Some code using this type relies on this (eg when copying it into
235 * guest memory or a gdb protocol buffer, or by using Int128 in
236 * a union with other integer types).
248 static inline Int128
int128_make64(uint64_t a
)
250 return (Int128
) { .lo
= a
, .hi
= 0 };
253 static inline Int128
int128_makes64(int64_t a
)
255 return (Int128
) { .lo
= a
, .hi
= a
>> 63 };
258 static inline Int128
int128_make128(uint64_t lo
, uint64_t hi
)
260 return (Int128
) { .lo
= lo
, .hi
= hi
};
263 static inline uint64_t int128_get64(Int128 a
)
269 static inline uint64_t int128_getlo(Int128 a
)
274 static inline int64_t int128_gethi(Int128 a
)
279 static inline Int128
int128_zero(void)
281 return int128_make64(0);
284 static inline Int128
int128_one(void)
286 return int128_make64(1);
289 static inline Int128
int128_2_64(void)
291 return int128_make128(0, 1);
294 static inline Int128
int128_exts64(int64_t a
)
296 return int128_make128(a
, (a
< 0) ? -1 : 0);
299 static inline Int128
int128_not(Int128 a
)
301 return int128_make128(~a
.lo
, ~a
.hi
);
304 static inline Int128
int128_and(Int128 a
, Int128 b
)
306 return int128_make128(a
.lo
& b
.lo
, a
.hi
& b
.hi
);
309 static inline Int128
int128_or(Int128 a
, Int128 b
)
311 return int128_make128(a
.lo
| b
.lo
, a
.hi
| b
.hi
);
314 static inline Int128
int128_xor(Int128 a
, Int128 b
)
316 return int128_make128(a
.lo
^ b
.lo
, a
.hi
^ b
.hi
);
319 static inline Int128
int128_rshift(Int128 a
, int n
)
325 h
= a
.hi
>> (n
& 63);
327 return int128_make128(h
, h
>> 63);
329 return int128_make128((a
.lo
>> n
) | ((uint64_t)a
.hi
<< (64 - n
)), h
);
333 static inline Int128
int128_urshift(Int128 a
, int n
)
341 return int128_make64(h
);
343 return int128_make128((a
.lo
>> n
) | ((uint64_t)a
.hi
<< (64 - n
)), h
);
347 static inline Int128
int128_lshift(Int128 a
, int n
)
349 uint64_t l
= a
.lo
<< (n
& 63);
351 return int128_make128(0, l
);
353 return int128_make128(l
, (a
.hi
<< n
) | (a
.lo
>> (64 - n
)));
358 static inline Int128
int128_add(Int128 a
, Int128 b
)
360 uint64_t lo
= a
.lo
+ b
.lo
;
362 /* a.lo <= a.lo + b.lo < a.lo + k (k is the base, 2^64). Hence,
363 * a.lo + b.lo >= k implies 0 <= lo = a.lo + b.lo - k < a.lo.
364 * Similarly, a.lo + b.lo < k implies a.lo <= lo = a.lo + b.lo < k.
366 * So the carry is lo < a.lo.
368 return int128_make128(lo
, (uint64_t)a
.hi
+ b
.hi
+ (lo
< a
.lo
));
371 static inline Int128
int128_neg(Int128 a
)
374 return int128_make128(lo
, ~(uint64_t)a
.hi
+ !lo
);
377 static inline Int128
int128_sub(Int128 a
, Int128 b
)
379 return int128_make128(a
.lo
- b
.lo
, (uint64_t)a
.hi
- b
.hi
- (a
.lo
< b
.lo
));
382 static inline bool int128_nonneg(Int128 a
)
387 static inline bool int128_eq(Int128 a
, Int128 b
)
389 return a
.lo
== b
.lo
&& a
.hi
== b
.hi
;
392 static inline bool int128_ne(Int128 a
, Int128 b
)
394 return !int128_eq(a
, b
);
397 static inline bool int128_ge(Int128 a
, Int128 b
)
399 return a
.hi
> b
.hi
|| (a
.hi
== b
.hi
&& a
.lo
>= b
.lo
);
402 static inline bool int128_uge(Int128 a
, Int128 b
)
404 return (uint64_t)a
.hi
> (uint64_t)b
.hi
|| (a
.hi
== b
.hi
&& a
.lo
>= b
.lo
);
407 static inline bool int128_lt(Int128 a
, Int128 b
)
409 return !int128_ge(a
, b
);
412 static inline bool int128_ult(Int128 a
, Int128 b
)
414 return !int128_uge(a
, b
);
417 static inline bool int128_le(Int128 a
, Int128 b
)
419 return int128_ge(b
, a
);
422 static inline bool int128_gt(Int128 a
, Int128 b
)
424 return !int128_le(a
, b
);
427 static inline bool int128_nz(Int128 a
)
432 static inline Int128
int128_min(Int128 a
, Int128 b
)
434 return int128_le(a
, b
) ? a
: b
;
437 static inline Int128
int128_max(Int128 a
, Int128 b
)
439 return int128_ge(a
, b
) ? a
: b
;
442 static inline void int128_addto(Int128
*a
, Int128 b
)
444 *a
= int128_add(*a
, b
);
447 static inline void int128_subfrom(Int128
*a
, Int128 b
)
449 *a
= int128_sub(*a
, b
);
452 static inline Int128
bswap128(Int128 a
)
454 return int128_make128(bswap64(a
.hi
), bswap64(a
.lo
));
457 static inline int clz128(Int128 a
)
460 return __builtin_clzll(a
.hi
);
462 return (a
.lo
) ? __builtin_clzll(a
.lo
) + 64 : 128;
466 Int128
int128_divu(Int128
, Int128
);
467 Int128
int128_remu(Int128
, Int128
);
468 Int128
int128_divs(Int128
, Int128
);
469 Int128
int128_rems(Int128
, Int128
);
470 #endif /* CONFIG_INT128 && !CONFIG_TCG_INTERPRETER */
472 static inline void bswap128s(Int128
*s
)
477 #define UINT128_MAX int128_make128(~0LL, ~0LL)
478 #define INT128_MAX int128_make128(UINT64_MAX, INT64_MAX)
479 #define INT128_MIN int128_make128(0, INT64_MIN)
482 * When compiler supports a 128-bit type, define a combination of
483 * a possible structure and the native types. Ease parameter passing
484 * via use of the transparent union extension.
486 #ifdef CONFIG_INT128_TYPE
491 } Int128Alias
__attribute__((transparent_union
));
493 typedef Int128 Int128Alias
;
494 #endif /* CONFIG_INT128_TYPE */
496 #endif /* INT128_H */