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