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
;
14 static inline Int128
int128_make64(uint64_t a
)
19 static inline Int128
int128_makes64(int64_t a
)
24 static inline Int128
int128_make128(uint64_t lo
, uint64_t hi
)
26 return (__uint128_t
)hi
<< 64 | lo
;
29 static inline uint64_t int128_get64(Int128 a
)
36 static inline uint64_t int128_getlo(Int128 a
)
41 static inline int64_t int128_gethi(Int128 a
)
46 static inline Int128
int128_zero(void)
51 static inline Int128
int128_one(void)
56 static inline Int128
int128_2_64(void)
58 return (Int128
)1 << 64;
61 static inline Int128
int128_exts64(int64_t a
)
66 static inline Int128
int128_not(Int128 a
)
71 static inline Int128
int128_and(Int128 a
, Int128 b
)
76 static inline Int128
int128_or(Int128 a
, Int128 b
)
81 static inline Int128
int128_xor(Int128 a
, Int128 b
)
86 static inline Int128
int128_rshift(Int128 a
, int n
)
91 static inline Int128
int128_urshift(Int128 a
, int n
)
93 return (__uint128_t
)a
>> n
;
96 static inline Int128
int128_lshift(Int128 a
, int n
)
101 static inline Int128
int128_add(Int128 a
, Int128 b
)
106 static inline Int128
int128_neg(Int128 a
)
111 static inline Int128
int128_sub(Int128 a
, Int128 b
)
116 static inline bool int128_nonneg(Int128 a
)
121 static inline bool int128_eq(Int128 a
, Int128 b
)
126 static inline bool int128_ne(Int128 a
, Int128 b
)
131 static inline bool int128_ge(Int128 a
, Int128 b
)
136 static inline bool int128_uge(Int128 a
, Int128 b
)
138 return ((__uint128_t
)a
) >= ((__uint128_t
)b
);
141 static inline bool int128_lt(Int128 a
, Int128 b
)
146 static inline bool int128_ult(Int128 a
, Int128 b
)
148 return (__uint128_t
)a
< (__uint128_t
)b
;
151 static inline bool int128_le(Int128 a
, Int128 b
)
156 static inline bool int128_gt(Int128 a
, Int128 b
)
161 static inline bool int128_nz(Int128 a
)
166 static inline Int128
int128_min(Int128 a
, Int128 b
)
168 return a
< b
? a
: b
;
171 static inline Int128
int128_max(Int128 a
, Int128 b
)
173 return a
> b
? a
: b
;
176 static inline void int128_addto(Int128
*a
, Int128 b
)
181 static inline void int128_subfrom(Int128
*a
, Int128 b
)
186 static inline Int128
bswap128(Int128 a
)
188 #if __has_builtin(__builtin_bswap128)
189 return __builtin_bswap128(a
);
191 return int128_make128(bswap64(int128_gethi(a
)), bswap64(int128_getlo(a
)));
195 static inline int clz128(Int128 a
)
198 return __builtin_clzll(a
>> 64);
200 return (a
) ? __builtin_clzll((uint64_t)a
) + 64 : 128;
204 static inline Int128
int128_divu(Int128 a
, Int128 b
)
206 return (__uint128_t
)a
/ (__uint128_t
)b
;
209 static inline Int128
int128_remu(Int128 a
, Int128 b
)
211 return (__uint128_t
)a
% (__uint128_t
)b
;
214 static inline Int128
int128_divs(Int128 a
, Int128 b
)
219 static inline Int128
int128_rems(Int128 a
, Int128 b
)
224 #else /* !CONFIG_INT128 */
226 typedef struct Int128 Int128
;
229 * We guarantee that the in-memory byte representation of an
230 * Int128 is that of a host-endian-order 128-bit integer
231 * (whether using this struct or the __int128_t version of the type).
232 * Some code using this type relies on this (eg when copying it into
233 * guest memory or a gdb protocol buffer, or by using Int128 in
234 * a union with other integer types).
246 static inline Int128
int128_make64(uint64_t a
)
248 return (Int128
) { .lo
= a
, .hi
= 0 };
251 static inline Int128
int128_makes64(int64_t a
)
253 return (Int128
) { .lo
= a
, .hi
= a
>> 63 };
256 static inline Int128
int128_make128(uint64_t lo
, uint64_t hi
)
258 return (Int128
) { .lo
= lo
, .hi
= hi
};
261 static inline uint64_t int128_get64(Int128 a
)
267 static inline uint64_t int128_getlo(Int128 a
)
272 static inline int64_t int128_gethi(Int128 a
)
277 static inline Int128
int128_zero(void)
279 return int128_make64(0);
282 static inline Int128
int128_one(void)
284 return int128_make64(1);
287 static inline Int128
int128_2_64(void)
289 return int128_make128(0, 1);
292 static inline Int128
int128_exts64(int64_t a
)
294 return int128_make128(a
, (a
< 0) ? -1 : 0);
297 static inline Int128
int128_not(Int128 a
)
299 return int128_make128(~a
.lo
, ~a
.hi
);
302 static inline Int128
int128_and(Int128 a
, Int128 b
)
304 return int128_make128(a
.lo
& b
.lo
, a
.hi
& b
.hi
);
307 static inline Int128
int128_or(Int128 a
, Int128 b
)
309 return int128_make128(a
.lo
| b
.lo
, a
.hi
| b
.hi
);
312 static inline Int128
int128_xor(Int128 a
, Int128 b
)
314 return int128_make128(a
.lo
^ b
.lo
, a
.hi
^ b
.hi
);
317 static inline Int128
int128_rshift(Int128 a
, int n
)
323 h
= a
.hi
>> (n
& 63);
325 return int128_make128(h
, h
>> 63);
327 return int128_make128((a
.lo
>> n
) | ((uint64_t)a
.hi
<< (64 - n
)), h
);
331 static inline Int128
int128_urshift(Int128 a
, int n
)
339 return int128_make64(h
);
341 return int128_make128((a
.lo
>> n
) | ((uint64_t)a
.hi
<< (64 - n
)), h
);
345 static inline Int128
int128_lshift(Int128 a
, int n
)
347 uint64_t l
= a
.lo
<< (n
& 63);
349 return int128_make128(0, l
);
351 return int128_make128(l
, (a
.hi
<< n
) | (a
.lo
>> (64 - n
)));
356 static inline Int128
int128_add(Int128 a
, Int128 b
)
358 uint64_t lo
= a
.lo
+ b
.lo
;
360 /* a.lo <= a.lo + b.lo < a.lo + k (k is the base, 2^64). Hence,
361 * a.lo + b.lo >= k implies 0 <= lo = a.lo + b.lo - k < a.lo.
362 * Similarly, a.lo + b.lo < k implies a.lo <= lo = a.lo + b.lo < k.
364 * So the carry is lo < a.lo.
366 return int128_make128(lo
, (uint64_t)a
.hi
+ b
.hi
+ (lo
< a
.lo
));
369 static inline Int128
int128_neg(Int128 a
)
372 return int128_make128(lo
, ~(uint64_t)a
.hi
+ !lo
);
375 static inline Int128
int128_sub(Int128 a
, Int128 b
)
377 return int128_make128(a
.lo
- b
.lo
, (uint64_t)a
.hi
- b
.hi
- (a
.lo
< b
.lo
));
380 static inline bool int128_nonneg(Int128 a
)
385 static inline bool int128_eq(Int128 a
, Int128 b
)
387 return a
.lo
== b
.lo
&& a
.hi
== b
.hi
;
390 static inline bool int128_ne(Int128 a
, Int128 b
)
392 return !int128_eq(a
, b
);
395 static inline bool int128_ge(Int128 a
, Int128 b
)
397 return a
.hi
> b
.hi
|| (a
.hi
== b
.hi
&& a
.lo
>= b
.lo
);
400 static inline bool int128_uge(Int128 a
, Int128 b
)
402 return (uint64_t)a
.hi
> (uint64_t)b
.hi
|| (a
.hi
== b
.hi
&& a
.lo
>= b
.lo
);
405 static inline bool int128_lt(Int128 a
, Int128 b
)
407 return !int128_ge(a
, b
);
410 static inline bool int128_ult(Int128 a
, Int128 b
)
412 return !int128_uge(a
, b
);
415 static inline bool int128_le(Int128 a
, Int128 b
)
417 return int128_ge(b
, a
);
420 static inline bool int128_gt(Int128 a
, Int128 b
)
422 return !int128_le(a
, b
);
425 static inline bool int128_nz(Int128 a
)
430 static inline Int128
int128_min(Int128 a
, Int128 b
)
432 return int128_le(a
, b
) ? a
: b
;
435 static inline Int128
int128_max(Int128 a
, Int128 b
)
437 return int128_ge(a
, b
) ? a
: b
;
440 static inline void int128_addto(Int128
*a
, Int128 b
)
442 *a
= int128_add(*a
, b
);
445 static inline void int128_subfrom(Int128
*a
, Int128 b
)
447 *a
= int128_sub(*a
, b
);
450 static inline Int128
bswap128(Int128 a
)
452 return int128_make128(bswap64(a
.hi
), bswap64(a
.lo
));
455 static inline int clz128(Int128 a
)
458 return __builtin_clzll(a
.hi
);
460 return (a
.lo
) ? __builtin_clzll(a
.lo
) + 64 : 128;
464 Int128
int128_divu(Int128
, Int128
);
465 Int128
int128_remu(Int128
, Int128
);
466 Int128
int128_divs(Int128
, Int128
);
467 Int128
int128_rems(Int128
, Int128
);
468 #endif /* CONFIG_INT128 && !CONFIG_TCG_INTERPRETER */
470 static inline void bswap128s(Int128
*s
)
475 #define UINT128_MAX int128_make128(~0LL, ~0LL)
476 #define INT128_MAX int128_make128(UINT64_MAX, INT64_MAX)
477 #define INT128_MIN int128_make128(0, INT64_MIN)
480 * When compiler supports a 128-bit type, define a combination of
481 * a possible structure and the native types. Ease parameter passing
482 * via use of the transparent union extension.
484 #ifdef CONFIG_INT128_TYPE
489 } Int128Alias
__attribute__((transparent_union
));
491 typedef Int128 Int128Alias
;
492 #endif /* CONFIG_INT128_TYPE */
494 #endif /* INT128_H */