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;
13*34aee9c9SThomas Huth typedef __int128_t __attribute__((aligned(16))) Int128Aligned;
140846beb3SRichard Henderson
int128_make64(uint64_t a)150846beb3SRichard Henderson static inline Int128 int128_make64(uint64_t a)
160846beb3SRichard Henderson {
170846beb3SRichard Henderson return a;
180846beb3SRichard Henderson }
190846beb3SRichard Henderson
int128_makes64(int64_t a)20703235a3SPeter Maydell static inline Int128 int128_makes64(int64_t a)
21703235a3SPeter Maydell {
22703235a3SPeter Maydell return a;
23703235a3SPeter Maydell }
24703235a3SPeter Maydell
int128_make128(uint64_t lo,uint64_t hi)251edaeee0SRichard Henderson static inline Int128 int128_make128(uint64_t lo, uint64_t hi)
261edaeee0SRichard Henderson {
271edaeee0SRichard Henderson return (__uint128_t)hi << 64 | lo;
281edaeee0SRichard Henderson }
291edaeee0SRichard Henderson
int128_get64(Int128 a)300846beb3SRichard Henderson static inline uint64_t int128_get64(Int128 a)
310846beb3SRichard Henderson {
320846beb3SRichard Henderson uint64_t r = a;
330846beb3SRichard Henderson assert(r == a);
340846beb3SRichard Henderson return r;
350846beb3SRichard Henderson }
360846beb3SRichard Henderson
int128_getlo(Int128 a)370846beb3SRichard Henderson static inline uint64_t int128_getlo(Int128 a)
380846beb3SRichard Henderson {
390846beb3SRichard Henderson return a;
400846beb3SRichard Henderson }
410846beb3SRichard Henderson
int128_gethi(Int128 a)420846beb3SRichard Henderson static inline int64_t int128_gethi(Int128 a)
430846beb3SRichard Henderson {
440846beb3SRichard Henderson return a >> 64;
450846beb3SRichard Henderson }
460846beb3SRichard Henderson
int128_zero(void)470846beb3SRichard Henderson static inline Int128 int128_zero(void)
480846beb3SRichard Henderson {
490846beb3SRichard Henderson return 0;
500846beb3SRichard Henderson }
510846beb3SRichard Henderson
int128_one(void)520846beb3SRichard Henderson static inline Int128 int128_one(void)
530846beb3SRichard Henderson {
540846beb3SRichard Henderson return 1;
550846beb3SRichard Henderson }
560846beb3SRichard Henderson
int128_2_64(void)570846beb3SRichard Henderson static inline Int128 int128_2_64(void)
580846beb3SRichard Henderson {
590846beb3SRichard Henderson return (Int128)1 << 64;
600846beb3SRichard Henderson }
610846beb3SRichard Henderson
int128_exts64(int64_t a)620846beb3SRichard Henderson static inline Int128 int128_exts64(int64_t a)
630846beb3SRichard Henderson {
640846beb3SRichard Henderson return a;
650846beb3SRichard Henderson }
660846beb3SRichard Henderson
int128_not(Int128 a)671c469373SFrédéric Pétrot static inline Int128 int128_not(Int128 a)
681c469373SFrédéric Pétrot {
691c469373SFrédéric Pétrot return ~a;
701c469373SFrédéric Pétrot }
711c469373SFrédéric Pétrot
int128_and(Int128 a,Int128 b)720846beb3SRichard Henderson static inline Int128 int128_and(Int128 a, Int128 b)
730846beb3SRichard Henderson {
740846beb3SRichard Henderson return a & b;
750846beb3SRichard Henderson }
760846beb3SRichard Henderson
int128_or(Int128 a,Int128 b)7708895cdaSRichard Henderson static inline Int128 int128_or(Int128 a, Int128 b)
7808895cdaSRichard Henderson {
7908895cdaSRichard Henderson return a | b;
8008895cdaSRichard Henderson }
8108895cdaSRichard Henderson
int128_xor(Int128 a,Int128 b)821c469373SFrédéric Pétrot static inline Int128 int128_xor(Int128 a, Int128 b)
831c469373SFrédéric Pétrot {
841c469373SFrédéric Pétrot return a ^ b;
851c469373SFrédéric Pétrot }
861c469373SFrédéric Pétrot
int128_rshift(Int128 a,int n)870846beb3SRichard Henderson static inline Int128 int128_rshift(Int128 a, int n)
880846beb3SRichard Henderson {
890846beb3SRichard Henderson return a >> n;
900846beb3SRichard Henderson }
910846beb3SRichard Henderson
int128_urshift(Int128 a,int n)92613cf0fcSMatheus Ferst static inline Int128 int128_urshift(Int128 a, int n)
93613cf0fcSMatheus Ferst {
94613cf0fcSMatheus Ferst return (__uint128_t)a >> n;
95613cf0fcSMatheus Ferst }
96613cf0fcSMatheus Ferst
int128_lshift(Int128 a,int n)975be4dd04SRichard Henderson static inline Int128 int128_lshift(Int128 a, int n)
985be4dd04SRichard Henderson {
995be4dd04SRichard Henderson return a << n;
1005be4dd04SRichard Henderson }
1015be4dd04SRichard Henderson
int128_add(Int128 a,Int128 b)1020846beb3SRichard Henderson static inline Int128 int128_add(Int128 a, Int128 b)
1030846beb3SRichard Henderson {
1040846beb3SRichard Henderson return a + b;
1050846beb3SRichard Henderson }
1060846beb3SRichard Henderson
int128_neg(Int128 a)1070846beb3SRichard Henderson static inline Int128 int128_neg(Int128 a)
1080846beb3SRichard Henderson {
1090846beb3SRichard Henderson return -a;
1100846beb3SRichard Henderson }
1110846beb3SRichard Henderson
int128_sub(Int128 a,Int128 b)1120846beb3SRichard Henderson static inline Int128 int128_sub(Int128 a, Int128 b)
1130846beb3SRichard Henderson {
1140846beb3SRichard Henderson return a - b;
1150846beb3SRichard Henderson }
1160846beb3SRichard Henderson
int128_nonneg(Int128 a)1170846beb3SRichard Henderson static inline bool int128_nonneg(Int128 a)
1180846beb3SRichard Henderson {
1190846beb3SRichard Henderson return a >= 0;
1200846beb3SRichard Henderson }
1210846beb3SRichard Henderson
int128_eq(Int128 a,Int128 b)1220846beb3SRichard Henderson static inline bool int128_eq(Int128 a, Int128 b)
1230846beb3SRichard Henderson {
1240846beb3SRichard Henderson return a == b;
1250846beb3SRichard Henderson }
1260846beb3SRichard Henderson
int128_ne(Int128 a,Int128 b)1270846beb3SRichard Henderson static inline bool int128_ne(Int128 a, Int128 b)
1280846beb3SRichard Henderson {
1290846beb3SRichard Henderson return a != b;
1300846beb3SRichard Henderson }
1310846beb3SRichard Henderson
int128_ge(Int128 a,Int128 b)1320846beb3SRichard Henderson static inline bool int128_ge(Int128 a, Int128 b)
1330846beb3SRichard Henderson {
1340846beb3SRichard Henderson return a >= b;
1350846beb3SRichard Henderson }
1360846beb3SRichard Henderson
int128_uge(Int128 a,Int128 b)1374724bbd2SLucas Mateus Castro (alqotel) static inline bool int128_uge(Int128 a, Int128 b)
1384724bbd2SLucas Mateus Castro (alqotel) {
1394724bbd2SLucas Mateus Castro (alqotel) return ((__uint128_t)a) >= ((__uint128_t)b);
1404724bbd2SLucas Mateus Castro (alqotel) }
1414724bbd2SLucas Mateus Castro (alqotel)
int128_lt(Int128 a,Int128 b)1420846beb3SRichard Henderson static inline bool int128_lt(Int128 a, Int128 b)
1430846beb3SRichard Henderson {
1440846beb3SRichard Henderson return a < b;
1450846beb3SRichard Henderson }
1460846beb3SRichard Henderson
int128_ult(Int128 a,Int128 b)1474724bbd2SLucas Mateus Castro (alqotel) static inline bool int128_ult(Int128 a, Int128 b)
1484724bbd2SLucas Mateus Castro (alqotel) {
1494724bbd2SLucas Mateus Castro (alqotel) return (__uint128_t)a < (__uint128_t)b;
1504724bbd2SLucas Mateus Castro (alqotel) }
1514724bbd2SLucas Mateus Castro (alqotel)
int128_le(Int128 a,Int128 b)1520846beb3SRichard Henderson static inline bool int128_le(Int128 a, Int128 b)
1530846beb3SRichard Henderson {
1540846beb3SRichard Henderson return a <= b;
1550846beb3SRichard Henderson }
1560846beb3SRichard Henderson
int128_gt(Int128 a,Int128 b)1570846beb3SRichard Henderson static inline bool int128_gt(Int128 a, Int128 b)
1580846beb3SRichard Henderson {
1590846beb3SRichard Henderson return a > b;
1600846beb3SRichard Henderson }
1610846beb3SRichard Henderson
int128_nz(Int128 a)1620846beb3SRichard Henderson static inline bool int128_nz(Int128 a)
1630846beb3SRichard Henderson {
1640846beb3SRichard Henderson return a != 0;
1650846beb3SRichard Henderson }
1660846beb3SRichard Henderson
int128_min(Int128 a,Int128 b)1670846beb3SRichard Henderson static inline Int128 int128_min(Int128 a, Int128 b)
1680846beb3SRichard Henderson {
1690846beb3SRichard Henderson return a < b ? a : b;
1700846beb3SRichard Henderson }
1710846beb3SRichard Henderson
int128_max(Int128 a,Int128 b)1720846beb3SRichard Henderson static inline Int128 int128_max(Int128 a, Int128 b)
1730846beb3SRichard Henderson {
1740846beb3SRichard Henderson return a > b ? a : b;
1750846beb3SRichard Henderson }
1760846beb3SRichard Henderson
int128_addto(Int128 * a,Int128 b)1770846beb3SRichard Henderson static inline void int128_addto(Int128 *a, Int128 b)
1780846beb3SRichard Henderson {
1790846beb3SRichard Henderson *a += b;
1800846beb3SRichard Henderson }
1810846beb3SRichard Henderson
int128_subfrom(Int128 * a,Int128 b)1820846beb3SRichard Henderson static inline void int128_subfrom(Int128 *a, Int128 b)
1830846beb3SRichard Henderson {
1840846beb3SRichard Henderson *a -= b;
1850846beb3SRichard Henderson }
1860846beb3SRichard Henderson
bswap128(Int128 a)1877ebee43eSRichard Henderson static inline Int128 bswap128(Int128 a)
1887ebee43eSRichard Henderson {
1892484cd9cSMatheus Ferst #if __has_builtin(__builtin_bswap128)
1902484cd9cSMatheus Ferst return __builtin_bswap128(a);
1912484cd9cSMatheus Ferst #else
1927ebee43eSRichard Henderson return int128_make128(bswap64(int128_gethi(a)), bswap64(int128_getlo(a)));
1932484cd9cSMatheus Ferst #endif
1947ebee43eSRichard Henderson }
1957ebee43eSRichard Henderson
clz128(Int128 a)1964724bbd2SLucas Mateus Castro (alqotel) static inline int clz128(Int128 a)
1974724bbd2SLucas Mateus Castro (alqotel) {
1984724bbd2SLucas Mateus Castro (alqotel) if (a >> 64) {
1994724bbd2SLucas Mateus Castro (alqotel) return __builtin_clzll(a >> 64);
2004724bbd2SLucas Mateus Castro (alqotel) } else {
2014724bbd2SLucas Mateus Castro (alqotel) return (a) ? __builtin_clzll((uint64_t)a) + 64 : 128;
2024724bbd2SLucas Mateus Castro (alqotel) }
2034724bbd2SLucas Mateus Castro (alqotel) }
2044724bbd2SLucas Mateus Castro (alqotel)
int128_divu(Int128 a,Int128 b)205e9d07601SFrédéric Pétrot static inline Int128 int128_divu(Int128 a, Int128 b)
206e9d07601SFrédéric Pétrot {
207e9d07601SFrédéric Pétrot return (__uint128_t)a / (__uint128_t)b;
208e9d07601SFrédéric Pétrot }
209e9d07601SFrédéric Pétrot
int128_remu(Int128 a,Int128 b)210e9d07601SFrédéric Pétrot static inline Int128 int128_remu(Int128 a, Int128 b)
211e9d07601SFrédéric Pétrot {
212e9d07601SFrédéric Pétrot return (__uint128_t)a % (__uint128_t)b;
213e9d07601SFrédéric Pétrot }
214e9d07601SFrédéric Pétrot
int128_divs(Int128 a,Int128 b)215e9d07601SFrédéric Pétrot static inline Int128 int128_divs(Int128 a, Int128 b)
216e9d07601SFrédéric Pétrot {
217e9d07601SFrédéric Pétrot return a / b;
218e9d07601SFrédéric Pétrot }
219e9d07601SFrédéric Pétrot
int128_rems(Int128 a,Int128 b)220e9d07601SFrédéric Pétrot static inline Int128 int128_rems(Int128 a, Int128 b)
221e9d07601SFrédéric Pétrot {
222e9d07601SFrédéric Pétrot return a % b;
223e9d07601SFrédéric Pétrot }
224e9d07601SFrédéric Pétrot
2250846beb3SRichard Henderson #else /* !CONFIG_INT128 */
2266046c620SPaolo Bonzini
227b7cd3db6SAvi Kivity typedef struct Int128 Int128;
228*34aee9c9SThomas Huth typedef struct Int128 __attribute__((aligned(16))) Int128Aligned;
229b7cd3db6SAvi Kivity
230181b0c33SMatheus Ferst /*
231181b0c33SMatheus Ferst * We guarantee that the in-memory byte representation of an
232181b0c33SMatheus Ferst * Int128 is that of a host-endian-order 128-bit integer
233181b0c33SMatheus Ferst * (whether using this struct or the __int128_t version of the type).
234181b0c33SMatheus Ferst * Some code using this type relies on this (eg when copying it into
235181b0c33SMatheus Ferst * guest memory or a gdb protocol buffer, or by using Int128 in
236181b0c33SMatheus Ferst * a union with other integer types).
237181b0c33SMatheus Ferst */
238b7cd3db6SAvi Kivity struct Int128 {
239e03b5686SMarc-André Lureau #if HOST_BIG_ENDIAN
240181b0c33SMatheus Ferst int64_t hi;
241181b0c33SMatheus Ferst uint64_t lo;
242181b0c33SMatheus Ferst #else
243b7cd3db6SAvi Kivity uint64_t lo;
244b7cd3db6SAvi Kivity int64_t hi;
245181b0c33SMatheus Ferst #endif
246b7cd3db6SAvi Kivity };
247b7cd3db6SAvi Kivity
int128_make64(uint64_t a)248b7cd3db6SAvi Kivity static inline Int128 int128_make64(uint64_t a)
249b7cd3db6SAvi Kivity {
250181b0c33SMatheus Ferst return (Int128) { .lo = a, .hi = 0 };
251b7cd3db6SAvi Kivity }
252b7cd3db6SAvi Kivity
int128_makes64(int64_t a)253703235a3SPeter Maydell static inline Int128 int128_makes64(int64_t a)
254703235a3SPeter Maydell {
255181b0c33SMatheus Ferst return (Int128) { .lo = a, .hi = a >> 63 };
256703235a3SPeter Maydell }
257703235a3SPeter Maydell
int128_make128(uint64_t lo,uint64_t hi)2581edaeee0SRichard Henderson static inline Int128 int128_make128(uint64_t lo, uint64_t hi)
2591edaeee0SRichard Henderson {
260181b0c33SMatheus Ferst return (Int128) { .lo = lo, .hi = hi };
2611edaeee0SRichard Henderson }
2621edaeee0SRichard Henderson
int128_get64(Int128 a)263b7cd3db6SAvi Kivity static inline uint64_t int128_get64(Int128 a)
264b7cd3db6SAvi Kivity {
265b7cd3db6SAvi Kivity assert(!a.hi);
266b7cd3db6SAvi Kivity return a.lo;
267b7cd3db6SAvi Kivity }
268b7cd3db6SAvi Kivity
int128_getlo(Int128 a)269258dfaaaSRichard Henderson static inline uint64_t int128_getlo(Int128 a)
270258dfaaaSRichard Henderson {
271258dfaaaSRichard Henderson return a.lo;
272258dfaaaSRichard Henderson }
273258dfaaaSRichard Henderson
int128_gethi(Int128 a)274258dfaaaSRichard Henderson static inline int64_t int128_gethi(Int128 a)
275258dfaaaSRichard Henderson {
276258dfaaaSRichard Henderson return a.hi;
277258dfaaaSRichard Henderson }
278258dfaaaSRichard Henderson
int128_zero(void)279b7cd3db6SAvi Kivity static inline Int128 int128_zero(void)
280b7cd3db6SAvi Kivity {
281b7cd3db6SAvi Kivity return int128_make64(0);
282b7cd3db6SAvi Kivity }
283b7cd3db6SAvi Kivity
int128_one(void)284b7cd3db6SAvi Kivity static inline Int128 int128_one(void)
285b7cd3db6SAvi Kivity {
286b7cd3db6SAvi Kivity return int128_make64(1);
287b7cd3db6SAvi Kivity }
288b7cd3db6SAvi Kivity
int128_2_64(void)289b7cd3db6SAvi Kivity static inline Int128 int128_2_64(void)
290b7cd3db6SAvi Kivity {
291181b0c33SMatheus Ferst return int128_make128(0, 1);
292b7cd3db6SAvi Kivity }
293b7cd3db6SAvi Kivity
int128_exts64(int64_t a)29412e1129bSAlexey Kardashevskiy static inline Int128 int128_exts64(int64_t a)
29512e1129bSAlexey Kardashevskiy {
296181b0c33SMatheus Ferst return int128_make128(a, (a < 0) ? -1 : 0);
29712e1129bSAlexey Kardashevskiy }
29812e1129bSAlexey Kardashevskiy
int128_not(Int128 a)2991c469373SFrédéric Pétrot static inline Int128 int128_not(Int128 a)
3001c469373SFrédéric Pétrot {
3011c469373SFrédéric Pétrot return int128_make128(~a.lo, ~a.hi);
3021c469373SFrédéric Pétrot }
3031c469373SFrédéric Pétrot
int128_and(Int128 a,Int128 b)304052e87b0SPaolo Bonzini static inline Int128 int128_and(Int128 a, Int128 b)
305052e87b0SPaolo Bonzini {
306181b0c33SMatheus Ferst return int128_make128(a.lo & b.lo, a.hi & b.hi);
307052e87b0SPaolo Bonzini }
308052e87b0SPaolo Bonzini
int128_or(Int128 a,Int128 b)30908895cdaSRichard Henderson static inline Int128 int128_or(Int128 a, Int128 b)
31008895cdaSRichard Henderson {
311181b0c33SMatheus Ferst return int128_make128(a.lo | b.lo, a.hi | b.hi);
31208895cdaSRichard Henderson }
31308895cdaSRichard Henderson
int128_xor(Int128 a,Int128 b)3141c469373SFrédéric Pétrot static inline Int128 int128_xor(Int128 a, Int128 b)
3151c469373SFrédéric Pétrot {
3161c469373SFrédéric Pétrot return int128_make128(a.lo ^ b.lo, a.hi ^ b.hi);
3171c469373SFrédéric Pétrot }
3181c469373SFrédéric Pétrot
int128_rshift(Int128 a,int n)319052e87b0SPaolo Bonzini static inline Int128 int128_rshift(Int128 a, int n)
320052e87b0SPaolo Bonzini {
321052e87b0SPaolo Bonzini int64_t h;
322052e87b0SPaolo Bonzini if (!n) {
323052e87b0SPaolo Bonzini return a;
324052e87b0SPaolo Bonzini }
325052e87b0SPaolo Bonzini h = a.hi >> (n & 63);
326052e87b0SPaolo Bonzini if (n >= 64) {
3271edaeee0SRichard Henderson return int128_make128(h, h >> 63);
328052e87b0SPaolo Bonzini } else {
3291edaeee0SRichard Henderson return int128_make128((a.lo >> n) | ((uint64_t)a.hi << (64 - n)), h);
330052e87b0SPaolo Bonzini }
331052e87b0SPaolo Bonzini }
332052e87b0SPaolo Bonzini
int128_urshift(Int128 a,int n)333613cf0fcSMatheus Ferst static inline Int128 int128_urshift(Int128 a, int n)
334613cf0fcSMatheus Ferst {
335613cf0fcSMatheus Ferst uint64_t h = a.hi;
336613cf0fcSMatheus Ferst if (!n) {
337613cf0fcSMatheus Ferst return a;
338613cf0fcSMatheus Ferst }
339613cf0fcSMatheus Ferst h = h >> (n & 63);
340613cf0fcSMatheus Ferst if (n >= 64) {
341613cf0fcSMatheus Ferst return int128_make64(h);
342613cf0fcSMatheus Ferst } else {
343613cf0fcSMatheus Ferst return int128_make128((a.lo >> n) | ((uint64_t)a.hi << (64 - n)), h);
344613cf0fcSMatheus Ferst }
345613cf0fcSMatheus Ferst }
346613cf0fcSMatheus Ferst
int128_lshift(Int128 a,int n)3475be4dd04SRichard Henderson static inline Int128 int128_lshift(Int128 a, int n)
3485be4dd04SRichard Henderson {
3495be4dd04SRichard Henderson uint64_t l = a.lo << (n & 63);
3505be4dd04SRichard Henderson if (n >= 64) {
3515be4dd04SRichard Henderson return int128_make128(0, l);
3525be4dd04SRichard Henderson } else if (n > 0) {
3535be4dd04SRichard Henderson return int128_make128(l, (a.hi << n) | (a.lo >> (64 - n)));
3545be4dd04SRichard Henderson }
3555be4dd04SRichard Henderson return a;
3565be4dd04SRichard Henderson }
3575be4dd04SRichard Henderson
int128_add(Int128 a,Int128 b)358b7cd3db6SAvi Kivity static inline Int128 int128_add(Int128 a, Int128 b)
359b7cd3db6SAvi Kivity {
3606046c620SPaolo Bonzini uint64_t lo = a.lo + b.lo;
3616046c620SPaolo Bonzini
3626046c620SPaolo Bonzini /* a.lo <= a.lo + b.lo < a.lo + k (k is the base, 2^64). Hence,
3636046c620SPaolo Bonzini * a.lo + b.lo >= k implies 0 <= lo = a.lo + b.lo - k < a.lo.
3646046c620SPaolo Bonzini * Similarly, a.lo + b.lo < k implies a.lo <= lo = a.lo + b.lo < k.
3656046c620SPaolo Bonzini *
3666046c620SPaolo Bonzini * So the carry is lo < a.lo.
3676046c620SPaolo Bonzini */
3681edaeee0SRichard Henderson return int128_make128(lo, (uint64_t)a.hi + b.hi + (lo < a.lo));
369b7cd3db6SAvi Kivity }
370b7cd3db6SAvi Kivity
int128_neg(Int128 a)371b7cd3db6SAvi Kivity static inline Int128 int128_neg(Int128 a)
372b7cd3db6SAvi Kivity {
3736046c620SPaolo Bonzini uint64_t lo = -a.lo;
3741edaeee0SRichard Henderson return int128_make128(lo, ~(uint64_t)a.hi + !lo);
375b7cd3db6SAvi Kivity }
376b7cd3db6SAvi Kivity
int128_sub(Int128 a,Int128 b)377b7cd3db6SAvi Kivity static inline Int128 int128_sub(Int128 a, Int128 b)
378b7cd3db6SAvi Kivity {
3791edaeee0SRichard Henderson return int128_make128(a.lo - b.lo, (uint64_t)a.hi - b.hi - (a.lo < b.lo));
380b7cd3db6SAvi Kivity }
381b7cd3db6SAvi Kivity
int128_nonneg(Int128 a)382b7cd3db6SAvi Kivity static inline bool int128_nonneg(Int128 a)
383b7cd3db6SAvi Kivity {
384b7cd3db6SAvi Kivity return a.hi >= 0;
385b7cd3db6SAvi Kivity }
386b7cd3db6SAvi Kivity
int128_eq(Int128 a,Int128 b)387b7cd3db6SAvi Kivity static inline bool int128_eq(Int128 a, Int128 b)
388b7cd3db6SAvi Kivity {
389b7cd3db6SAvi Kivity return a.lo == b.lo && a.hi == b.hi;
390b7cd3db6SAvi Kivity }
391b7cd3db6SAvi Kivity
int128_ne(Int128 a,Int128 b)392b7cd3db6SAvi Kivity static inline bool int128_ne(Int128 a, Int128 b)
393b7cd3db6SAvi Kivity {
394b7cd3db6SAvi Kivity return !int128_eq(a, b);
395b7cd3db6SAvi Kivity }
396b7cd3db6SAvi Kivity
int128_ge(Int128 a,Int128 b)397b7cd3db6SAvi Kivity static inline bool int128_ge(Int128 a, Int128 b)
398b7cd3db6SAvi Kivity {
3996046c620SPaolo Bonzini return a.hi > b.hi || (a.hi == b.hi && a.lo >= b.lo);
400b7cd3db6SAvi Kivity }
401b7cd3db6SAvi Kivity
int128_uge(Int128 a,Int128 b)4024724bbd2SLucas Mateus Castro (alqotel) static inline bool int128_uge(Int128 a, Int128 b)
4034724bbd2SLucas Mateus Castro (alqotel) {
4044724bbd2SLucas Mateus Castro (alqotel) return (uint64_t)a.hi > (uint64_t)b.hi || (a.hi == b.hi && a.lo >= b.lo);
4054724bbd2SLucas Mateus Castro (alqotel) }
4064724bbd2SLucas Mateus Castro (alqotel)
int128_lt(Int128 a,Int128 b)407b7cd3db6SAvi Kivity static inline bool int128_lt(Int128 a, Int128 b)
408b7cd3db6SAvi Kivity {
409b7cd3db6SAvi Kivity return !int128_ge(a, b);
410b7cd3db6SAvi Kivity }
411b7cd3db6SAvi Kivity
int128_ult(Int128 a,Int128 b)4124724bbd2SLucas Mateus Castro (alqotel) static inline bool int128_ult(Int128 a, Int128 b)
4134724bbd2SLucas Mateus Castro (alqotel) {
4144724bbd2SLucas Mateus Castro (alqotel) return !int128_uge(a, b);
4154724bbd2SLucas Mateus Castro (alqotel) }
4164724bbd2SLucas Mateus Castro (alqotel)
int128_le(Int128 a,Int128 b)417b7cd3db6SAvi Kivity static inline bool int128_le(Int128 a, Int128 b)
418b7cd3db6SAvi Kivity {
419b7cd3db6SAvi Kivity return int128_ge(b, a);
420b7cd3db6SAvi Kivity }
421b7cd3db6SAvi Kivity
int128_gt(Int128 a,Int128 b)422b7cd3db6SAvi Kivity static inline bool int128_gt(Int128 a, Int128 b)
423b7cd3db6SAvi Kivity {
424b7cd3db6SAvi Kivity return !int128_le(a, b);
425b7cd3db6SAvi Kivity }
426b7cd3db6SAvi Kivity
int128_nz(Int128 a)427b7cd3db6SAvi Kivity static inline bool int128_nz(Int128 a)
428b7cd3db6SAvi Kivity {
429b7cd3db6SAvi Kivity return a.lo || a.hi;
430b7cd3db6SAvi Kivity }
431b7cd3db6SAvi Kivity
int128_min(Int128 a,Int128 b)432b7cd3db6SAvi Kivity static inline Int128 int128_min(Int128 a, Int128 b)
433b7cd3db6SAvi Kivity {
434b7cd3db6SAvi Kivity return int128_le(a, b) ? a : b;
435b7cd3db6SAvi Kivity }
436b7cd3db6SAvi Kivity
int128_max(Int128 a,Int128 b)437b7cd3db6SAvi Kivity static inline Int128 int128_max(Int128 a, Int128 b)
438b7cd3db6SAvi Kivity {
439b7cd3db6SAvi Kivity return int128_ge(a, b) ? a : b;
440b7cd3db6SAvi Kivity }
441b7cd3db6SAvi Kivity
int128_addto(Int128 * a,Int128 b)442b7cd3db6SAvi Kivity static inline void int128_addto(Int128 *a, Int128 b)
443b7cd3db6SAvi Kivity {
444b7cd3db6SAvi Kivity *a = int128_add(*a, b);
445b7cd3db6SAvi Kivity }
446b7cd3db6SAvi Kivity
int128_subfrom(Int128 * a,Int128 b)447b7cd3db6SAvi Kivity static inline void int128_subfrom(Int128 *a, Int128 b)
448b7cd3db6SAvi Kivity {
449b7cd3db6SAvi Kivity *a = int128_sub(*a, b);
450b7cd3db6SAvi Kivity }
451b7cd3db6SAvi Kivity
bswap128(Int128 a)4522484cd9cSMatheus Ferst static inline Int128 bswap128(Int128 a)
4532484cd9cSMatheus Ferst {
4542484cd9cSMatheus Ferst return int128_make128(bswap64(a.hi), bswap64(a.lo));
4552484cd9cSMatheus Ferst }
4562484cd9cSMatheus Ferst
clz128(Int128 a)4574724bbd2SLucas Mateus Castro (alqotel) static inline int clz128(Int128 a)
4584724bbd2SLucas Mateus Castro (alqotel) {
4594724bbd2SLucas Mateus Castro (alqotel) if (a.hi) {
4604724bbd2SLucas Mateus Castro (alqotel) return __builtin_clzll(a.hi);
4614724bbd2SLucas Mateus Castro (alqotel) } else {
4624724bbd2SLucas Mateus Castro (alqotel) return (a.lo) ? __builtin_clzll(a.lo) + 64 : 128;
4634724bbd2SLucas Mateus Castro (alqotel) }
4644724bbd2SLucas Mateus Castro (alqotel) }
4654724bbd2SLucas Mateus Castro (alqotel)
466e9d07601SFrédéric Pétrot Int128 int128_divu(Int128, Int128);
467e9d07601SFrédéric Pétrot Int128 int128_remu(Int128, Int128);
468e9d07601SFrédéric Pétrot Int128 int128_divs(Int128, Int128);
469e9d07601SFrédéric Pétrot Int128 int128_rems(Int128, Int128);
470b959822cSRichard Henderson #endif /* CONFIG_INT128 && !CONFIG_TCG_INTERPRETER */
4712484cd9cSMatheus Ferst
bswap128s(Int128 * s)4722484cd9cSMatheus Ferst static inline void bswap128s(Int128 *s)
4732484cd9cSMatheus Ferst {
4742484cd9cSMatheus Ferst *s = bswap128(*s);
4752484cd9cSMatheus Ferst }
4762484cd9cSMatheus Ferst
477e9d07601SFrédéric Pétrot #define UINT128_MAX int128_make128(~0LL, ~0LL)
478bea59230SMatheus Ferst #define INT128_MAX int128_make128(UINT64_MAX, INT64_MAX)
479bea59230SMatheus Ferst #define INT128_MIN int128_make128(0, INT64_MIN)
480e9d07601SFrédéric Pétrot
481b959822cSRichard Henderson /*
482b959822cSRichard Henderson * When compiler supports a 128-bit type, define a combination of
483b959822cSRichard Henderson * a possible structure and the native types. Ease parameter passing
484b959822cSRichard Henderson * via use of the transparent union extension.
485b959822cSRichard Henderson */
4866479dd74SRichard Henderson #ifdef CONFIG_INT128_TYPE
487b959822cSRichard Henderson typedef union {
488b959822cSRichard Henderson __uint128_t u;
489c4075353SRichard Henderson __int128_t i;
490c4075353SRichard Henderson Int128 s;
491b959822cSRichard Henderson } Int128Alias __attribute__((transparent_union));
492b959822cSRichard Henderson #else
493b959822cSRichard Henderson typedef Int128 Int128Alias;
4946479dd74SRichard Henderson #endif /* CONFIG_INT128_TYPE */
495b959822cSRichard Henderson
4960846beb3SRichard Henderson #endif /* INT128_H */
497