xref: /qemu/include/qemu/int128.h (revision 6479dd74f14d51f207509aa1b77b039b7bd32bff)
1b7cd3db6SAvi Kivity #ifndef INT128_H
2b7cd3db6SAvi Kivity #define INT128_H
3b7cd3db6SAvi Kivity 
47ebee43eSRichard Henderson #include "qemu/bswap.h"
50846beb3SRichard Henderson 
6b959822cSRichard Henderson /*
7b959822cSRichard Henderson  * With TCI, we need to use libffi for interfacing with TCG helpers.
8b959822cSRichard Henderson  * But libffi does not support __int128_t, and therefore cannot pass
9b959822cSRichard Henderson  * or return values of this type, force use of the Int128 struct.
10b959822cSRichard Henderson  */
11b959822cSRichard Henderson #if defined(CONFIG_INT128) && !defined(CONFIG_TCG_INTERPRETER)
120846beb3SRichard Henderson typedef __int128_t Int128;
130846beb3SRichard Henderson 
140846beb3SRichard Henderson static inline Int128 int128_make64(uint64_t a)
150846beb3SRichard Henderson {
160846beb3SRichard Henderson     return a;
170846beb3SRichard Henderson }
180846beb3SRichard Henderson 
19703235a3SPeter Maydell static inline Int128 int128_makes64(int64_t a)
20703235a3SPeter Maydell {
21703235a3SPeter Maydell     return a;
22703235a3SPeter Maydell }
23703235a3SPeter Maydell 
241edaeee0SRichard Henderson static inline Int128 int128_make128(uint64_t lo, uint64_t hi)
251edaeee0SRichard Henderson {
261edaeee0SRichard Henderson     return (__uint128_t)hi << 64 | lo;
271edaeee0SRichard Henderson }
281edaeee0SRichard Henderson 
290846beb3SRichard Henderson static inline uint64_t int128_get64(Int128 a)
300846beb3SRichard Henderson {
310846beb3SRichard Henderson     uint64_t r = a;
320846beb3SRichard Henderson     assert(r == a);
330846beb3SRichard Henderson     return r;
340846beb3SRichard Henderson }
350846beb3SRichard Henderson 
360846beb3SRichard Henderson static inline uint64_t int128_getlo(Int128 a)
370846beb3SRichard Henderson {
380846beb3SRichard Henderson     return a;
390846beb3SRichard Henderson }
400846beb3SRichard Henderson 
410846beb3SRichard Henderson static inline int64_t int128_gethi(Int128 a)
420846beb3SRichard Henderson {
430846beb3SRichard Henderson     return a >> 64;
440846beb3SRichard Henderson }
450846beb3SRichard Henderson 
460846beb3SRichard Henderson static inline Int128 int128_zero(void)
470846beb3SRichard Henderson {
480846beb3SRichard Henderson     return 0;
490846beb3SRichard Henderson }
500846beb3SRichard Henderson 
510846beb3SRichard Henderson static inline Int128 int128_one(void)
520846beb3SRichard Henderson {
530846beb3SRichard Henderson     return 1;
540846beb3SRichard Henderson }
550846beb3SRichard Henderson 
560846beb3SRichard Henderson static inline Int128 int128_2_64(void)
570846beb3SRichard Henderson {
580846beb3SRichard Henderson     return (Int128)1 << 64;
590846beb3SRichard Henderson }
600846beb3SRichard Henderson 
610846beb3SRichard Henderson static inline Int128 int128_exts64(int64_t a)
620846beb3SRichard Henderson {
630846beb3SRichard Henderson     return a;
640846beb3SRichard Henderson }
650846beb3SRichard Henderson 
661c469373SFrédéric Pétrot static inline Int128 int128_not(Int128 a)
671c469373SFrédéric Pétrot {
681c469373SFrédéric Pétrot     return ~a;
691c469373SFrédéric Pétrot }
701c469373SFrédéric Pétrot 
710846beb3SRichard Henderson static inline Int128 int128_and(Int128 a, Int128 b)
720846beb3SRichard Henderson {
730846beb3SRichard Henderson     return a & b;
740846beb3SRichard Henderson }
750846beb3SRichard Henderson 
7608895cdaSRichard Henderson static inline Int128 int128_or(Int128 a, Int128 b)
7708895cdaSRichard Henderson {
7808895cdaSRichard Henderson     return a | b;
7908895cdaSRichard Henderson }
8008895cdaSRichard Henderson 
811c469373SFrédéric Pétrot static inline Int128 int128_xor(Int128 a, Int128 b)
821c469373SFrédéric Pétrot {
831c469373SFrédéric Pétrot     return a ^ b;
841c469373SFrédéric Pétrot }
851c469373SFrédéric Pétrot 
860846beb3SRichard Henderson static inline Int128 int128_rshift(Int128 a, int n)
870846beb3SRichard Henderson {
880846beb3SRichard Henderson     return a >> n;
890846beb3SRichard Henderson }
900846beb3SRichard Henderson 
91613cf0fcSMatheus Ferst static inline Int128 int128_urshift(Int128 a, int n)
92613cf0fcSMatheus Ferst {
93613cf0fcSMatheus Ferst     return (__uint128_t)a >> n;
94613cf0fcSMatheus Ferst }
95613cf0fcSMatheus Ferst 
965be4dd04SRichard Henderson static inline Int128 int128_lshift(Int128 a, int n)
975be4dd04SRichard Henderson {
985be4dd04SRichard Henderson     return a << n;
995be4dd04SRichard Henderson }
1005be4dd04SRichard Henderson 
1010846beb3SRichard Henderson static inline Int128 int128_add(Int128 a, Int128 b)
1020846beb3SRichard Henderson {
1030846beb3SRichard Henderson     return a + b;
1040846beb3SRichard Henderson }
1050846beb3SRichard Henderson 
1060846beb3SRichard Henderson static inline Int128 int128_neg(Int128 a)
1070846beb3SRichard Henderson {
1080846beb3SRichard Henderson     return -a;
1090846beb3SRichard Henderson }
1100846beb3SRichard Henderson 
1110846beb3SRichard Henderson static inline Int128 int128_sub(Int128 a, Int128 b)
1120846beb3SRichard Henderson {
1130846beb3SRichard Henderson     return a - b;
1140846beb3SRichard Henderson }
1150846beb3SRichard Henderson 
1160846beb3SRichard Henderson static inline bool int128_nonneg(Int128 a)
1170846beb3SRichard Henderson {
1180846beb3SRichard Henderson     return a >= 0;
1190846beb3SRichard Henderson }
1200846beb3SRichard Henderson 
1210846beb3SRichard Henderson static inline bool int128_eq(Int128 a, Int128 b)
1220846beb3SRichard Henderson {
1230846beb3SRichard Henderson     return a == b;
1240846beb3SRichard Henderson }
1250846beb3SRichard Henderson 
1260846beb3SRichard Henderson static inline bool int128_ne(Int128 a, Int128 b)
1270846beb3SRichard Henderson {
1280846beb3SRichard Henderson     return a != b;
1290846beb3SRichard Henderson }
1300846beb3SRichard Henderson 
1310846beb3SRichard Henderson static inline bool int128_ge(Int128 a, Int128 b)
1320846beb3SRichard Henderson {
1330846beb3SRichard Henderson     return a >= b;
1340846beb3SRichard Henderson }
1350846beb3SRichard Henderson 
1364724bbd2SLucas Mateus Castro (alqotel) static inline bool int128_uge(Int128 a, Int128 b)
1374724bbd2SLucas Mateus Castro (alqotel) {
1384724bbd2SLucas Mateus Castro (alqotel)     return ((__uint128_t)a) >= ((__uint128_t)b);
1394724bbd2SLucas Mateus Castro (alqotel) }
1404724bbd2SLucas Mateus Castro (alqotel) 
1410846beb3SRichard Henderson static inline bool int128_lt(Int128 a, Int128 b)
1420846beb3SRichard Henderson {
1430846beb3SRichard Henderson     return a < b;
1440846beb3SRichard Henderson }
1450846beb3SRichard Henderson 
1464724bbd2SLucas Mateus Castro (alqotel) static inline bool int128_ult(Int128 a, Int128 b)
1474724bbd2SLucas Mateus Castro (alqotel) {
1484724bbd2SLucas Mateus Castro (alqotel)     return (__uint128_t)a < (__uint128_t)b;
1494724bbd2SLucas Mateus Castro (alqotel) }
1504724bbd2SLucas Mateus Castro (alqotel) 
1510846beb3SRichard Henderson static inline bool int128_le(Int128 a, Int128 b)
1520846beb3SRichard Henderson {
1530846beb3SRichard Henderson     return a <= b;
1540846beb3SRichard Henderson }
1550846beb3SRichard Henderson 
1560846beb3SRichard Henderson static inline bool int128_gt(Int128 a, Int128 b)
1570846beb3SRichard Henderson {
1580846beb3SRichard Henderson     return a > b;
1590846beb3SRichard Henderson }
1600846beb3SRichard Henderson 
1610846beb3SRichard Henderson static inline bool int128_nz(Int128 a)
1620846beb3SRichard Henderson {
1630846beb3SRichard Henderson     return a != 0;
1640846beb3SRichard Henderson }
1650846beb3SRichard Henderson 
1660846beb3SRichard Henderson static inline Int128 int128_min(Int128 a, Int128 b)
1670846beb3SRichard Henderson {
1680846beb3SRichard Henderson     return a < b ? a : b;
1690846beb3SRichard Henderson }
1700846beb3SRichard Henderson 
1710846beb3SRichard Henderson static inline Int128 int128_max(Int128 a, Int128 b)
1720846beb3SRichard Henderson {
1730846beb3SRichard Henderson     return a > b ? a : b;
1740846beb3SRichard Henderson }
1750846beb3SRichard Henderson 
1760846beb3SRichard Henderson static inline void int128_addto(Int128 *a, Int128 b)
1770846beb3SRichard Henderson {
1780846beb3SRichard Henderson     *a += b;
1790846beb3SRichard Henderson }
1800846beb3SRichard Henderson 
1810846beb3SRichard Henderson static inline void int128_subfrom(Int128 *a, Int128 b)
1820846beb3SRichard Henderson {
1830846beb3SRichard Henderson     *a -= b;
1840846beb3SRichard Henderson }
1850846beb3SRichard Henderson 
1867ebee43eSRichard Henderson static inline Int128 bswap128(Int128 a)
1877ebee43eSRichard Henderson {
1882484cd9cSMatheus Ferst #if __has_builtin(__builtin_bswap128)
1892484cd9cSMatheus Ferst     return __builtin_bswap128(a);
1902484cd9cSMatheus Ferst #else
1917ebee43eSRichard Henderson     return int128_make128(bswap64(int128_gethi(a)), bswap64(int128_getlo(a)));
1922484cd9cSMatheus Ferst #endif
1937ebee43eSRichard Henderson }
1947ebee43eSRichard Henderson 
1954724bbd2SLucas Mateus Castro (alqotel) static inline int clz128(Int128 a)
1964724bbd2SLucas Mateus Castro (alqotel) {
1974724bbd2SLucas Mateus Castro (alqotel)     if (a >> 64) {
1984724bbd2SLucas Mateus Castro (alqotel)         return __builtin_clzll(a >> 64);
1994724bbd2SLucas Mateus Castro (alqotel)     } else {
2004724bbd2SLucas Mateus Castro (alqotel)         return (a) ? __builtin_clzll((uint64_t)a) + 64 : 128;
2014724bbd2SLucas Mateus Castro (alqotel)     }
2024724bbd2SLucas Mateus Castro (alqotel) }
2034724bbd2SLucas Mateus Castro (alqotel) 
204e9d07601SFrédéric Pétrot static inline Int128 int128_divu(Int128 a, Int128 b)
205e9d07601SFrédéric Pétrot {
206e9d07601SFrédéric Pétrot     return (__uint128_t)a / (__uint128_t)b;
207e9d07601SFrédéric Pétrot }
208e9d07601SFrédéric Pétrot 
209e9d07601SFrédéric Pétrot static inline Int128 int128_remu(Int128 a, Int128 b)
210e9d07601SFrédéric Pétrot {
211e9d07601SFrédéric Pétrot     return (__uint128_t)a % (__uint128_t)b;
212e9d07601SFrédéric Pétrot }
213e9d07601SFrédéric Pétrot 
214e9d07601SFrédéric Pétrot static inline Int128 int128_divs(Int128 a, Int128 b)
215e9d07601SFrédéric Pétrot {
216e9d07601SFrédéric Pétrot     return a / b;
217e9d07601SFrédéric Pétrot }
218e9d07601SFrédéric Pétrot 
219e9d07601SFrédéric Pétrot static inline Int128 int128_rems(Int128 a, Int128 b)
220e9d07601SFrédéric Pétrot {
221e9d07601SFrédéric Pétrot     return a % b;
222e9d07601SFrédéric Pétrot }
223e9d07601SFrédéric Pétrot 
2240846beb3SRichard Henderson #else /* !CONFIG_INT128 */
2256046c620SPaolo Bonzini 
226b7cd3db6SAvi Kivity typedef struct Int128 Int128;
227b7cd3db6SAvi Kivity 
228181b0c33SMatheus Ferst /*
229181b0c33SMatheus Ferst  * We guarantee that the in-memory byte representation of an
230181b0c33SMatheus Ferst  * Int128 is that of a host-endian-order 128-bit integer
231181b0c33SMatheus Ferst  * (whether using this struct or the __int128_t version of the type).
232181b0c33SMatheus Ferst  * Some code using this type relies on this (eg when copying it into
233181b0c33SMatheus Ferst  * guest memory or a gdb protocol buffer, or by using Int128 in
234181b0c33SMatheus Ferst  * a union with other integer types).
235181b0c33SMatheus Ferst  */
236b7cd3db6SAvi Kivity struct Int128 {
237e03b5686SMarc-André Lureau #if HOST_BIG_ENDIAN
238181b0c33SMatheus Ferst     int64_t hi;
239181b0c33SMatheus Ferst     uint64_t lo;
240181b0c33SMatheus Ferst #else
241b7cd3db6SAvi Kivity     uint64_t lo;
242b7cd3db6SAvi Kivity     int64_t hi;
243181b0c33SMatheus Ferst #endif
244b7cd3db6SAvi Kivity };
245b7cd3db6SAvi Kivity 
246b7cd3db6SAvi Kivity static inline Int128 int128_make64(uint64_t a)
247b7cd3db6SAvi Kivity {
248181b0c33SMatheus Ferst     return (Int128) { .lo = a, .hi = 0 };
249b7cd3db6SAvi Kivity }
250b7cd3db6SAvi Kivity 
251703235a3SPeter Maydell static inline Int128 int128_makes64(int64_t a)
252703235a3SPeter Maydell {
253181b0c33SMatheus Ferst     return (Int128) { .lo = a, .hi = a >> 63 };
254703235a3SPeter Maydell }
255703235a3SPeter Maydell 
2561edaeee0SRichard Henderson static inline Int128 int128_make128(uint64_t lo, uint64_t hi)
2571edaeee0SRichard Henderson {
258181b0c33SMatheus Ferst     return (Int128) { .lo = lo, .hi = hi };
2591edaeee0SRichard Henderson }
2601edaeee0SRichard Henderson 
261b7cd3db6SAvi Kivity static inline uint64_t int128_get64(Int128 a)
262b7cd3db6SAvi Kivity {
263b7cd3db6SAvi Kivity     assert(!a.hi);
264b7cd3db6SAvi Kivity     return a.lo;
265b7cd3db6SAvi Kivity }
266b7cd3db6SAvi Kivity 
267258dfaaaSRichard Henderson static inline uint64_t int128_getlo(Int128 a)
268258dfaaaSRichard Henderson {
269258dfaaaSRichard Henderson     return a.lo;
270258dfaaaSRichard Henderson }
271258dfaaaSRichard Henderson 
272258dfaaaSRichard Henderson static inline int64_t int128_gethi(Int128 a)
273258dfaaaSRichard Henderson {
274258dfaaaSRichard Henderson     return a.hi;
275258dfaaaSRichard Henderson }
276258dfaaaSRichard Henderson 
277b7cd3db6SAvi Kivity static inline Int128 int128_zero(void)
278b7cd3db6SAvi Kivity {
279b7cd3db6SAvi Kivity     return int128_make64(0);
280b7cd3db6SAvi Kivity }
281b7cd3db6SAvi Kivity 
282b7cd3db6SAvi Kivity static inline Int128 int128_one(void)
283b7cd3db6SAvi Kivity {
284b7cd3db6SAvi Kivity     return int128_make64(1);
285b7cd3db6SAvi Kivity }
286b7cd3db6SAvi Kivity 
287b7cd3db6SAvi Kivity static inline Int128 int128_2_64(void)
288b7cd3db6SAvi Kivity {
289181b0c33SMatheus Ferst     return int128_make128(0, 1);
290b7cd3db6SAvi Kivity }
291b7cd3db6SAvi Kivity 
29212e1129bSAlexey Kardashevskiy static inline Int128 int128_exts64(int64_t a)
29312e1129bSAlexey Kardashevskiy {
294181b0c33SMatheus Ferst     return int128_make128(a, (a < 0) ? -1 : 0);
29512e1129bSAlexey Kardashevskiy }
29612e1129bSAlexey Kardashevskiy 
2971c469373SFrédéric Pétrot static inline Int128 int128_not(Int128 a)
2981c469373SFrédéric Pétrot {
2991c469373SFrédéric Pétrot     return int128_make128(~a.lo, ~a.hi);
3001c469373SFrédéric Pétrot }
3011c469373SFrédéric Pétrot 
302052e87b0SPaolo Bonzini static inline Int128 int128_and(Int128 a, Int128 b)
303052e87b0SPaolo Bonzini {
304181b0c33SMatheus Ferst     return int128_make128(a.lo & b.lo, a.hi & b.hi);
305052e87b0SPaolo Bonzini }
306052e87b0SPaolo Bonzini 
30708895cdaSRichard Henderson static inline Int128 int128_or(Int128 a, Int128 b)
30808895cdaSRichard Henderson {
309181b0c33SMatheus Ferst     return int128_make128(a.lo | b.lo, a.hi | b.hi);
31008895cdaSRichard Henderson }
31108895cdaSRichard Henderson 
3121c469373SFrédéric Pétrot static inline Int128 int128_xor(Int128 a, Int128 b)
3131c469373SFrédéric Pétrot {
3141c469373SFrédéric Pétrot     return int128_make128(a.lo ^ b.lo, a.hi ^ b.hi);
3151c469373SFrédéric Pétrot }
3161c469373SFrédéric Pétrot 
317052e87b0SPaolo Bonzini static inline Int128 int128_rshift(Int128 a, int n)
318052e87b0SPaolo Bonzini {
319052e87b0SPaolo Bonzini     int64_t h;
320052e87b0SPaolo Bonzini     if (!n) {
321052e87b0SPaolo Bonzini         return a;
322052e87b0SPaolo Bonzini     }
323052e87b0SPaolo Bonzini     h = a.hi >> (n & 63);
324052e87b0SPaolo Bonzini     if (n >= 64) {
3251edaeee0SRichard Henderson         return int128_make128(h, h >> 63);
326052e87b0SPaolo Bonzini     } else {
3271edaeee0SRichard Henderson         return int128_make128((a.lo >> n) | ((uint64_t)a.hi << (64 - n)), h);
328052e87b0SPaolo Bonzini     }
329052e87b0SPaolo Bonzini }
330052e87b0SPaolo Bonzini 
331613cf0fcSMatheus Ferst static inline Int128 int128_urshift(Int128 a, int n)
332613cf0fcSMatheus Ferst {
333613cf0fcSMatheus Ferst     uint64_t h = a.hi;
334613cf0fcSMatheus Ferst     if (!n) {
335613cf0fcSMatheus Ferst         return a;
336613cf0fcSMatheus Ferst     }
337613cf0fcSMatheus Ferst     h = h >> (n & 63);
338613cf0fcSMatheus Ferst     if (n >= 64) {
339613cf0fcSMatheus Ferst         return int128_make64(h);
340613cf0fcSMatheus Ferst     } else {
341613cf0fcSMatheus Ferst         return int128_make128((a.lo >> n) | ((uint64_t)a.hi << (64 - n)), h);
342613cf0fcSMatheus Ferst     }
343613cf0fcSMatheus Ferst }
344613cf0fcSMatheus Ferst 
3455be4dd04SRichard Henderson static inline Int128 int128_lshift(Int128 a, int n)
3465be4dd04SRichard Henderson {
3475be4dd04SRichard Henderson     uint64_t l = a.lo << (n & 63);
3485be4dd04SRichard Henderson     if (n >= 64) {
3495be4dd04SRichard Henderson         return int128_make128(0, l);
3505be4dd04SRichard Henderson     } else if (n > 0) {
3515be4dd04SRichard Henderson         return int128_make128(l, (a.hi << n) | (a.lo >> (64 - n)));
3525be4dd04SRichard Henderson     }
3535be4dd04SRichard Henderson     return a;
3545be4dd04SRichard Henderson }
3555be4dd04SRichard Henderson 
356b7cd3db6SAvi Kivity static inline Int128 int128_add(Int128 a, Int128 b)
357b7cd3db6SAvi Kivity {
3586046c620SPaolo Bonzini     uint64_t lo = a.lo + b.lo;
3596046c620SPaolo Bonzini 
3606046c620SPaolo Bonzini     /* a.lo <= a.lo + b.lo < a.lo + k (k is the base, 2^64).  Hence,
3616046c620SPaolo Bonzini      * a.lo + b.lo >= k implies 0 <= lo = a.lo + b.lo - k < a.lo.
3626046c620SPaolo Bonzini      * Similarly, a.lo + b.lo < k implies a.lo <= lo = a.lo + b.lo < k.
3636046c620SPaolo Bonzini      *
3646046c620SPaolo Bonzini      * So the carry is lo < a.lo.
3656046c620SPaolo Bonzini      */
3661edaeee0SRichard Henderson     return int128_make128(lo, (uint64_t)a.hi + b.hi + (lo < a.lo));
367b7cd3db6SAvi Kivity }
368b7cd3db6SAvi Kivity 
369b7cd3db6SAvi Kivity static inline Int128 int128_neg(Int128 a)
370b7cd3db6SAvi Kivity {
3716046c620SPaolo Bonzini     uint64_t lo = -a.lo;
3721edaeee0SRichard Henderson     return int128_make128(lo, ~(uint64_t)a.hi + !lo);
373b7cd3db6SAvi Kivity }
374b7cd3db6SAvi Kivity 
375b7cd3db6SAvi Kivity static inline Int128 int128_sub(Int128 a, Int128 b)
376b7cd3db6SAvi Kivity {
3771edaeee0SRichard Henderson     return int128_make128(a.lo - b.lo, (uint64_t)a.hi - b.hi - (a.lo < b.lo));
378b7cd3db6SAvi Kivity }
379b7cd3db6SAvi Kivity 
380b7cd3db6SAvi Kivity static inline bool int128_nonneg(Int128 a)
381b7cd3db6SAvi Kivity {
382b7cd3db6SAvi Kivity     return a.hi >= 0;
383b7cd3db6SAvi Kivity }
384b7cd3db6SAvi Kivity 
385b7cd3db6SAvi Kivity static inline bool int128_eq(Int128 a, Int128 b)
386b7cd3db6SAvi Kivity {
387b7cd3db6SAvi Kivity     return a.lo == b.lo && a.hi == b.hi;
388b7cd3db6SAvi Kivity }
389b7cd3db6SAvi Kivity 
390b7cd3db6SAvi Kivity static inline bool int128_ne(Int128 a, Int128 b)
391b7cd3db6SAvi Kivity {
392b7cd3db6SAvi Kivity     return !int128_eq(a, b);
393b7cd3db6SAvi Kivity }
394b7cd3db6SAvi Kivity 
395b7cd3db6SAvi Kivity static inline bool int128_ge(Int128 a, Int128 b)
396b7cd3db6SAvi Kivity {
3976046c620SPaolo Bonzini     return a.hi > b.hi || (a.hi == b.hi && a.lo >= b.lo);
398b7cd3db6SAvi Kivity }
399b7cd3db6SAvi Kivity 
4004724bbd2SLucas Mateus Castro (alqotel) static inline bool int128_uge(Int128 a, Int128 b)
4014724bbd2SLucas Mateus Castro (alqotel) {
4024724bbd2SLucas Mateus Castro (alqotel)     return (uint64_t)a.hi > (uint64_t)b.hi || (a.hi == b.hi && a.lo >= b.lo);
4034724bbd2SLucas Mateus Castro (alqotel) }
4044724bbd2SLucas Mateus Castro (alqotel) 
405b7cd3db6SAvi Kivity static inline bool int128_lt(Int128 a, Int128 b)
406b7cd3db6SAvi Kivity {
407b7cd3db6SAvi Kivity     return !int128_ge(a, b);
408b7cd3db6SAvi Kivity }
409b7cd3db6SAvi Kivity 
4104724bbd2SLucas Mateus Castro (alqotel) static inline bool int128_ult(Int128 a, Int128 b)
4114724bbd2SLucas Mateus Castro (alqotel) {
4124724bbd2SLucas Mateus Castro (alqotel)     return !int128_uge(a, b);
4134724bbd2SLucas Mateus Castro (alqotel) }
4144724bbd2SLucas Mateus Castro (alqotel) 
415b7cd3db6SAvi Kivity static inline bool int128_le(Int128 a, Int128 b)
416b7cd3db6SAvi Kivity {
417b7cd3db6SAvi Kivity     return int128_ge(b, a);
418b7cd3db6SAvi Kivity }
419b7cd3db6SAvi Kivity 
420b7cd3db6SAvi Kivity static inline bool int128_gt(Int128 a, Int128 b)
421b7cd3db6SAvi Kivity {
422b7cd3db6SAvi Kivity     return !int128_le(a, b);
423b7cd3db6SAvi Kivity }
424b7cd3db6SAvi Kivity 
425b7cd3db6SAvi Kivity static inline bool int128_nz(Int128 a)
426b7cd3db6SAvi Kivity {
427b7cd3db6SAvi Kivity     return a.lo || a.hi;
428b7cd3db6SAvi Kivity }
429b7cd3db6SAvi Kivity 
430b7cd3db6SAvi Kivity static inline Int128 int128_min(Int128 a, Int128 b)
431b7cd3db6SAvi Kivity {
432b7cd3db6SAvi Kivity     return int128_le(a, b) ? a : b;
433b7cd3db6SAvi Kivity }
434b7cd3db6SAvi Kivity 
435b7cd3db6SAvi Kivity static inline Int128 int128_max(Int128 a, Int128 b)
436b7cd3db6SAvi Kivity {
437b7cd3db6SAvi Kivity     return int128_ge(a, b) ? a : b;
438b7cd3db6SAvi Kivity }
439b7cd3db6SAvi Kivity 
440b7cd3db6SAvi Kivity static inline void int128_addto(Int128 *a, Int128 b)
441b7cd3db6SAvi Kivity {
442b7cd3db6SAvi Kivity     *a = int128_add(*a, b);
443b7cd3db6SAvi Kivity }
444b7cd3db6SAvi Kivity 
445b7cd3db6SAvi Kivity static inline void int128_subfrom(Int128 *a, Int128 b)
446b7cd3db6SAvi Kivity {
447b7cd3db6SAvi Kivity     *a = int128_sub(*a, b);
448b7cd3db6SAvi Kivity }
449b7cd3db6SAvi Kivity 
4502484cd9cSMatheus Ferst static inline Int128 bswap128(Int128 a)
4512484cd9cSMatheus Ferst {
4522484cd9cSMatheus Ferst     return int128_make128(bswap64(a.hi), bswap64(a.lo));
4532484cd9cSMatheus Ferst }
4542484cd9cSMatheus Ferst 
4554724bbd2SLucas Mateus Castro (alqotel) static inline int clz128(Int128 a)
4564724bbd2SLucas Mateus Castro (alqotel) {
4574724bbd2SLucas Mateus Castro (alqotel)     if (a.hi) {
4584724bbd2SLucas Mateus Castro (alqotel)         return __builtin_clzll(a.hi);
4594724bbd2SLucas Mateus Castro (alqotel)     } else {
4604724bbd2SLucas Mateus Castro (alqotel)         return (a.lo) ? __builtin_clzll(a.lo) + 64 : 128;
4614724bbd2SLucas Mateus Castro (alqotel)     }
4624724bbd2SLucas Mateus Castro (alqotel) }
4634724bbd2SLucas Mateus Castro (alqotel) 
464e9d07601SFrédéric Pétrot Int128 int128_divu(Int128, Int128);
465e9d07601SFrédéric Pétrot Int128 int128_remu(Int128, Int128);
466e9d07601SFrédéric Pétrot Int128 int128_divs(Int128, Int128);
467e9d07601SFrédéric Pétrot Int128 int128_rems(Int128, Int128);
468b959822cSRichard Henderson #endif /* CONFIG_INT128 && !CONFIG_TCG_INTERPRETER */
4692484cd9cSMatheus Ferst 
4702484cd9cSMatheus Ferst static inline void bswap128s(Int128 *s)
4712484cd9cSMatheus Ferst {
4722484cd9cSMatheus Ferst     *s = bswap128(*s);
4732484cd9cSMatheus Ferst }
4742484cd9cSMatheus Ferst 
475e9d07601SFrédéric Pétrot #define UINT128_MAX int128_make128(~0LL, ~0LL)
476bea59230SMatheus Ferst #define INT128_MAX int128_make128(UINT64_MAX, INT64_MAX)
477bea59230SMatheus Ferst #define INT128_MIN int128_make128(0, INT64_MIN)
478e9d07601SFrédéric Pétrot 
479b959822cSRichard Henderson /*
480b959822cSRichard Henderson  * When compiler supports a 128-bit type, define a combination of
481b959822cSRichard Henderson  * a possible structure and the native types.  Ease parameter passing
482b959822cSRichard Henderson  * via use of the transparent union extension.
483b959822cSRichard Henderson  */
484*6479dd74SRichard Henderson #ifdef CONFIG_INT128_TYPE
485b959822cSRichard Henderson typedef union {
486b959822cSRichard Henderson     __uint128_t u;
487c4075353SRichard Henderson     __int128_t i;
488c4075353SRichard Henderson     Int128 s;
489b959822cSRichard Henderson } Int128Alias __attribute__((transparent_union));
490b959822cSRichard Henderson #else
491b959822cSRichard Henderson typedef Int128 Int128Alias;
492*6479dd74SRichard Henderson #endif /* CONFIG_INT128_TYPE */
493b959822cSRichard Henderson 
4940846beb3SRichard Henderson #endif /* INT128_H */
495