1b7cd3db6SAvi Kivity #ifndef INT128_H 2b7cd3db6SAvi Kivity #define INT128_H 3b7cd3db6SAvi Kivity 47ebee43eSRichard Henderson #include "qemu/bswap.h" 50846beb3SRichard Henderson 62484cd9cSMatheus Ferst #ifdef CONFIG_INT128 70846beb3SRichard Henderson typedef __int128_t Int128; 80846beb3SRichard Henderson 90846beb3SRichard Henderson static inline Int128 int128_make64(uint64_t a) 100846beb3SRichard Henderson { 110846beb3SRichard Henderson return a; 120846beb3SRichard Henderson } 130846beb3SRichard Henderson 14703235a3SPeter Maydell static inline Int128 int128_makes64(int64_t a) 15703235a3SPeter Maydell { 16703235a3SPeter Maydell return a; 17703235a3SPeter Maydell } 18703235a3SPeter Maydell 191edaeee0SRichard Henderson static inline Int128 int128_make128(uint64_t lo, uint64_t hi) 201edaeee0SRichard Henderson { 211edaeee0SRichard Henderson return (__uint128_t)hi << 64 | lo; 221edaeee0SRichard Henderson } 231edaeee0SRichard Henderson 240846beb3SRichard Henderson static inline uint64_t int128_get64(Int128 a) 250846beb3SRichard Henderson { 260846beb3SRichard Henderson uint64_t r = a; 270846beb3SRichard Henderson assert(r == a); 280846beb3SRichard Henderson return r; 290846beb3SRichard Henderson } 300846beb3SRichard Henderson 310846beb3SRichard Henderson static inline uint64_t int128_getlo(Int128 a) 320846beb3SRichard Henderson { 330846beb3SRichard Henderson return a; 340846beb3SRichard Henderson } 350846beb3SRichard Henderson 360846beb3SRichard Henderson static inline int64_t int128_gethi(Int128 a) 370846beb3SRichard Henderson { 380846beb3SRichard Henderson return a >> 64; 390846beb3SRichard Henderson } 400846beb3SRichard Henderson 410846beb3SRichard Henderson static inline Int128 int128_zero(void) 420846beb3SRichard Henderson { 430846beb3SRichard Henderson return 0; 440846beb3SRichard Henderson } 450846beb3SRichard Henderson 460846beb3SRichard Henderson static inline Int128 int128_one(void) 470846beb3SRichard Henderson { 480846beb3SRichard Henderson return 1; 490846beb3SRichard Henderson } 500846beb3SRichard Henderson 510846beb3SRichard Henderson static inline Int128 int128_2_64(void) 520846beb3SRichard Henderson { 530846beb3SRichard Henderson return (Int128)1 << 64; 540846beb3SRichard Henderson } 550846beb3SRichard Henderson 560846beb3SRichard Henderson static inline Int128 int128_exts64(int64_t a) 570846beb3SRichard Henderson { 580846beb3SRichard Henderson return a; 590846beb3SRichard Henderson } 600846beb3SRichard Henderson 611c469373SFrédéric Pétrot static inline Int128 int128_not(Int128 a) 621c469373SFrédéric Pétrot { 631c469373SFrédéric Pétrot return ~a; 641c469373SFrédéric Pétrot } 651c469373SFrédéric Pétrot 660846beb3SRichard Henderson static inline Int128 int128_and(Int128 a, Int128 b) 670846beb3SRichard Henderson { 680846beb3SRichard Henderson return a & b; 690846beb3SRichard Henderson } 700846beb3SRichard Henderson 7108895cdaSRichard Henderson static inline Int128 int128_or(Int128 a, Int128 b) 7208895cdaSRichard Henderson { 7308895cdaSRichard Henderson return a | b; 7408895cdaSRichard Henderson } 7508895cdaSRichard Henderson 761c469373SFrédéric Pétrot static inline Int128 int128_xor(Int128 a, Int128 b) 771c469373SFrédéric Pétrot { 781c469373SFrédéric Pétrot return a ^ b; 791c469373SFrédéric Pétrot } 801c469373SFrédéric Pétrot 810846beb3SRichard Henderson static inline Int128 int128_rshift(Int128 a, int n) 820846beb3SRichard Henderson { 830846beb3SRichard Henderson return a >> n; 840846beb3SRichard Henderson } 850846beb3SRichard Henderson 86613cf0fcSMatheus Ferst static inline Int128 int128_urshift(Int128 a, int n) 87613cf0fcSMatheus Ferst { 88613cf0fcSMatheus Ferst return (__uint128_t)a >> n; 89613cf0fcSMatheus Ferst } 90613cf0fcSMatheus Ferst 915be4dd04SRichard Henderson static inline Int128 int128_lshift(Int128 a, int n) 925be4dd04SRichard Henderson { 935be4dd04SRichard Henderson return a << n; 945be4dd04SRichard Henderson } 955be4dd04SRichard Henderson 960846beb3SRichard Henderson static inline Int128 int128_add(Int128 a, Int128 b) 970846beb3SRichard Henderson { 980846beb3SRichard Henderson return a + b; 990846beb3SRichard Henderson } 1000846beb3SRichard Henderson 1010846beb3SRichard Henderson static inline Int128 int128_neg(Int128 a) 1020846beb3SRichard Henderson { 1030846beb3SRichard Henderson return -a; 1040846beb3SRichard Henderson } 1050846beb3SRichard Henderson 1060846beb3SRichard Henderson static inline Int128 int128_sub(Int128 a, Int128 b) 1070846beb3SRichard Henderson { 1080846beb3SRichard Henderson return a - b; 1090846beb3SRichard Henderson } 1100846beb3SRichard Henderson 1110846beb3SRichard Henderson static inline bool int128_nonneg(Int128 a) 1120846beb3SRichard Henderson { 1130846beb3SRichard Henderson return a >= 0; 1140846beb3SRichard Henderson } 1150846beb3SRichard Henderson 1160846beb3SRichard Henderson static inline bool int128_eq(Int128 a, Int128 b) 1170846beb3SRichard Henderson { 1180846beb3SRichard Henderson return a == b; 1190846beb3SRichard Henderson } 1200846beb3SRichard Henderson 1210846beb3SRichard Henderson static inline bool int128_ne(Int128 a, Int128 b) 1220846beb3SRichard Henderson { 1230846beb3SRichard Henderson return a != b; 1240846beb3SRichard Henderson } 1250846beb3SRichard Henderson 1260846beb3SRichard Henderson static inline bool int128_ge(Int128 a, Int128 b) 1270846beb3SRichard Henderson { 1280846beb3SRichard Henderson return a >= b; 1290846beb3SRichard Henderson } 1300846beb3SRichard Henderson 131*4724bbd2SLucas Mateus Castro (alqotel) static inline bool int128_uge(Int128 a, Int128 b) 132*4724bbd2SLucas Mateus Castro (alqotel) { 133*4724bbd2SLucas Mateus Castro (alqotel) return ((__uint128_t)a) >= ((__uint128_t)b); 134*4724bbd2SLucas Mateus Castro (alqotel) } 135*4724bbd2SLucas Mateus Castro (alqotel) 1360846beb3SRichard Henderson static inline bool int128_lt(Int128 a, Int128 b) 1370846beb3SRichard Henderson { 1380846beb3SRichard Henderson return a < b; 1390846beb3SRichard Henderson } 1400846beb3SRichard Henderson 141*4724bbd2SLucas Mateus Castro (alqotel) static inline bool int128_ult(Int128 a, Int128 b) 142*4724bbd2SLucas Mateus Castro (alqotel) { 143*4724bbd2SLucas Mateus Castro (alqotel) return (__uint128_t)a < (__uint128_t)b; 144*4724bbd2SLucas Mateus Castro (alqotel) } 145*4724bbd2SLucas Mateus Castro (alqotel) 1460846beb3SRichard Henderson static inline bool int128_le(Int128 a, Int128 b) 1470846beb3SRichard Henderson { 1480846beb3SRichard Henderson return a <= b; 1490846beb3SRichard Henderson } 1500846beb3SRichard Henderson 1510846beb3SRichard Henderson static inline bool int128_gt(Int128 a, Int128 b) 1520846beb3SRichard Henderson { 1530846beb3SRichard Henderson return a > b; 1540846beb3SRichard Henderson } 1550846beb3SRichard Henderson 1560846beb3SRichard Henderson static inline bool int128_nz(Int128 a) 1570846beb3SRichard Henderson { 1580846beb3SRichard Henderson return a != 0; 1590846beb3SRichard Henderson } 1600846beb3SRichard Henderson 1610846beb3SRichard Henderson static inline Int128 int128_min(Int128 a, Int128 b) 1620846beb3SRichard Henderson { 1630846beb3SRichard Henderson return a < b ? a : b; 1640846beb3SRichard Henderson } 1650846beb3SRichard Henderson 1660846beb3SRichard Henderson static inline Int128 int128_max(Int128 a, Int128 b) 1670846beb3SRichard Henderson { 1680846beb3SRichard Henderson return a > b ? a : b; 1690846beb3SRichard Henderson } 1700846beb3SRichard Henderson 1710846beb3SRichard Henderson static inline void int128_addto(Int128 *a, Int128 b) 1720846beb3SRichard Henderson { 1730846beb3SRichard Henderson *a += b; 1740846beb3SRichard Henderson } 1750846beb3SRichard Henderson 1760846beb3SRichard Henderson static inline void int128_subfrom(Int128 *a, Int128 b) 1770846beb3SRichard Henderson { 1780846beb3SRichard Henderson *a -= b; 1790846beb3SRichard Henderson } 1800846beb3SRichard Henderson 1817ebee43eSRichard Henderson static inline Int128 bswap128(Int128 a) 1827ebee43eSRichard Henderson { 1832484cd9cSMatheus Ferst #if __has_builtin(__builtin_bswap128) 1842484cd9cSMatheus Ferst return __builtin_bswap128(a); 1852484cd9cSMatheus Ferst #else 1867ebee43eSRichard Henderson return int128_make128(bswap64(int128_gethi(a)), bswap64(int128_getlo(a))); 1872484cd9cSMatheus Ferst #endif 1887ebee43eSRichard Henderson } 1897ebee43eSRichard Henderson 190*4724bbd2SLucas Mateus Castro (alqotel) static inline int clz128(Int128 a) 191*4724bbd2SLucas Mateus Castro (alqotel) { 192*4724bbd2SLucas Mateus Castro (alqotel) if (a >> 64) { 193*4724bbd2SLucas Mateus Castro (alqotel) return __builtin_clzll(a >> 64); 194*4724bbd2SLucas Mateus Castro (alqotel) } else { 195*4724bbd2SLucas Mateus Castro (alqotel) return (a) ? __builtin_clzll((uint64_t)a) + 64 : 128; 196*4724bbd2SLucas Mateus Castro (alqotel) } 197*4724bbd2SLucas Mateus Castro (alqotel) } 198*4724bbd2SLucas Mateus Castro (alqotel) 199e9d07601SFrédéric Pétrot static inline Int128 int128_divu(Int128 a, Int128 b) 200e9d07601SFrédéric Pétrot { 201e9d07601SFrédéric Pétrot return (__uint128_t)a / (__uint128_t)b; 202e9d07601SFrédéric Pétrot } 203e9d07601SFrédéric Pétrot 204e9d07601SFrédéric Pétrot static inline Int128 int128_remu(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_divs(Int128 a, Int128 b) 210e9d07601SFrédéric Pétrot { 211e9d07601SFrédéric Pétrot return a / b; 212e9d07601SFrédéric Pétrot } 213e9d07601SFrédéric Pétrot 214e9d07601SFrédéric Pétrot static inline Int128 int128_rems(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 2190846beb3SRichard Henderson #else /* !CONFIG_INT128 */ 2206046c620SPaolo Bonzini 221b7cd3db6SAvi Kivity typedef struct Int128 Int128; 222b7cd3db6SAvi Kivity 223181b0c33SMatheus Ferst /* 224181b0c33SMatheus Ferst * We guarantee that the in-memory byte representation of an 225181b0c33SMatheus Ferst * Int128 is that of a host-endian-order 128-bit integer 226181b0c33SMatheus Ferst * (whether using this struct or the __int128_t version of the type). 227181b0c33SMatheus Ferst * Some code using this type relies on this (eg when copying it into 228181b0c33SMatheus Ferst * guest memory or a gdb protocol buffer, or by using Int128 in 229181b0c33SMatheus Ferst * a union with other integer types). 230181b0c33SMatheus Ferst */ 231b7cd3db6SAvi Kivity struct Int128 { 232e03b5686SMarc-André Lureau #if HOST_BIG_ENDIAN 233181b0c33SMatheus Ferst int64_t hi; 234181b0c33SMatheus Ferst uint64_t lo; 235181b0c33SMatheus Ferst #else 236b7cd3db6SAvi Kivity uint64_t lo; 237b7cd3db6SAvi Kivity int64_t hi; 238181b0c33SMatheus Ferst #endif 239b7cd3db6SAvi Kivity }; 240b7cd3db6SAvi Kivity 241b7cd3db6SAvi Kivity static inline Int128 int128_make64(uint64_t a) 242b7cd3db6SAvi Kivity { 243181b0c33SMatheus Ferst return (Int128) { .lo = a, .hi = 0 }; 244b7cd3db6SAvi Kivity } 245b7cd3db6SAvi Kivity 246703235a3SPeter Maydell static inline Int128 int128_makes64(int64_t a) 247703235a3SPeter Maydell { 248181b0c33SMatheus Ferst return (Int128) { .lo = a, .hi = a >> 63 }; 249703235a3SPeter Maydell } 250703235a3SPeter Maydell 2511edaeee0SRichard Henderson static inline Int128 int128_make128(uint64_t lo, uint64_t hi) 2521edaeee0SRichard Henderson { 253181b0c33SMatheus Ferst return (Int128) { .lo = lo, .hi = hi }; 2541edaeee0SRichard Henderson } 2551edaeee0SRichard Henderson 256b7cd3db6SAvi Kivity static inline uint64_t int128_get64(Int128 a) 257b7cd3db6SAvi Kivity { 258b7cd3db6SAvi Kivity assert(!a.hi); 259b7cd3db6SAvi Kivity return a.lo; 260b7cd3db6SAvi Kivity } 261b7cd3db6SAvi Kivity 262258dfaaaSRichard Henderson static inline uint64_t int128_getlo(Int128 a) 263258dfaaaSRichard Henderson { 264258dfaaaSRichard Henderson return a.lo; 265258dfaaaSRichard Henderson } 266258dfaaaSRichard Henderson 267258dfaaaSRichard Henderson static inline int64_t int128_gethi(Int128 a) 268258dfaaaSRichard Henderson { 269258dfaaaSRichard Henderson return a.hi; 270258dfaaaSRichard Henderson } 271258dfaaaSRichard Henderson 272b7cd3db6SAvi Kivity static inline Int128 int128_zero(void) 273b7cd3db6SAvi Kivity { 274b7cd3db6SAvi Kivity return int128_make64(0); 275b7cd3db6SAvi Kivity } 276b7cd3db6SAvi Kivity 277b7cd3db6SAvi Kivity static inline Int128 int128_one(void) 278b7cd3db6SAvi Kivity { 279b7cd3db6SAvi Kivity return int128_make64(1); 280b7cd3db6SAvi Kivity } 281b7cd3db6SAvi Kivity 282b7cd3db6SAvi Kivity static inline Int128 int128_2_64(void) 283b7cd3db6SAvi Kivity { 284181b0c33SMatheus Ferst return int128_make128(0, 1); 285b7cd3db6SAvi Kivity } 286b7cd3db6SAvi Kivity 28712e1129bSAlexey Kardashevskiy static inline Int128 int128_exts64(int64_t a) 28812e1129bSAlexey Kardashevskiy { 289181b0c33SMatheus Ferst return int128_make128(a, (a < 0) ? -1 : 0); 29012e1129bSAlexey Kardashevskiy } 29112e1129bSAlexey Kardashevskiy 2921c469373SFrédéric Pétrot static inline Int128 int128_not(Int128 a) 2931c469373SFrédéric Pétrot { 2941c469373SFrédéric Pétrot return int128_make128(~a.lo, ~a.hi); 2951c469373SFrédéric Pétrot } 2961c469373SFrédéric Pétrot 297052e87b0SPaolo Bonzini static inline Int128 int128_and(Int128 a, Int128 b) 298052e87b0SPaolo Bonzini { 299181b0c33SMatheus Ferst return int128_make128(a.lo & b.lo, a.hi & b.hi); 300052e87b0SPaolo Bonzini } 301052e87b0SPaolo Bonzini 30208895cdaSRichard Henderson static inline Int128 int128_or(Int128 a, Int128 b) 30308895cdaSRichard Henderson { 304181b0c33SMatheus Ferst return int128_make128(a.lo | b.lo, a.hi | b.hi); 30508895cdaSRichard Henderson } 30608895cdaSRichard Henderson 3071c469373SFrédéric Pétrot static inline Int128 int128_xor(Int128 a, Int128 b) 3081c469373SFrédéric Pétrot { 3091c469373SFrédéric Pétrot return int128_make128(a.lo ^ b.lo, a.hi ^ b.hi); 3101c469373SFrédéric Pétrot } 3111c469373SFrédéric Pétrot 312052e87b0SPaolo Bonzini static inline Int128 int128_rshift(Int128 a, int n) 313052e87b0SPaolo Bonzini { 314052e87b0SPaolo Bonzini int64_t h; 315052e87b0SPaolo Bonzini if (!n) { 316052e87b0SPaolo Bonzini return a; 317052e87b0SPaolo Bonzini } 318052e87b0SPaolo Bonzini h = a.hi >> (n & 63); 319052e87b0SPaolo Bonzini if (n >= 64) { 3201edaeee0SRichard Henderson return int128_make128(h, h >> 63); 321052e87b0SPaolo Bonzini } else { 3221edaeee0SRichard Henderson return int128_make128((a.lo >> n) | ((uint64_t)a.hi << (64 - n)), h); 323052e87b0SPaolo Bonzini } 324052e87b0SPaolo Bonzini } 325052e87b0SPaolo Bonzini 326613cf0fcSMatheus Ferst static inline Int128 int128_urshift(Int128 a, int n) 327613cf0fcSMatheus Ferst { 328613cf0fcSMatheus Ferst uint64_t h = a.hi; 329613cf0fcSMatheus Ferst if (!n) { 330613cf0fcSMatheus Ferst return a; 331613cf0fcSMatheus Ferst } 332613cf0fcSMatheus Ferst h = h >> (n & 63); 333613cf0fcSMatheus Ferst if (n >= 64) { 334613cf0fcSMatheus Ferst return int128_make64(h); 335613cf0fcSMatheus Ferst } else { 336613cf0fcSMatheus Ferst return int128_make128((a.lo >> n) | ((uint64_t)a.hi << (64 - n)), h); 337613cf0fcSMatheus Ferst } 338613cf0fcSMatheus Ferst } 339613cf0fcSMatheus Ferst 3405be4dd04SRichard Henderson static inline Int128 int128_lshift(Int128 a, int n) 3415be4dd04SRichard Henderson { 3425be4dd04SRichard Henderson uint64_t l = a.lo << (n & 63); 3435be4dd04SRichard Henderson if (n >= 64) { 3445be4dd04SRichard Henderson return int128_make128(0, l); 3455be4dd04SRichard Henderson } else if (n > 0) { 3465be4dd04SRichard Henderson return int128_make128(l, (a.hi << n) | (a.lo >> (64 - n))); 3475be4dd04SRichard Henderson } 3485be4dd04SRichard Henderson return a; 3495be4dd04SRichard Henderson } 3505be4dd04SRichard Henderson 351b7cd3db6SAvi Kivity static inline Int128 int128_add(Int128 a, Int128 b) 352b7cd3db6SAvi Kivity { 3536046c620SPaolo Bonzini uint64_t lo = a.lo + b.lo; 3546046c620SPaolo Bonzini 3556046c620SPaolo Bonzini /* a.lo <= a.lo + b.lo < a.lo + k (k is the base, 2^64). Hence, 3566046c620SPaolo Bonzini * a.lo + b.lo >= k implies 0 <= lo = a.lo + b.lo - k < a.lo. 3576046c620SPaolo Bonzini * Similarly, a.lo + b.lo < k implies a.lo <= lo = a.lo + b.lo < k. 3586046c620SPaolo Bonzini * 3596046c620SPaolo Bonzini * So the carry is lo < a.lo. 3606046c620SPaolo Bonzini */ 3611edaeee0SRichard Henderson return int128_make128(lo, (uint64_t)a.hi + b.hi + (lo < a.lo)); 362b7cd3db6SAvi Kivity } 363b7cd3db6SAvi Kivity 364b7cd3db6SAvi Kivity static inline Int128 int128_neg(Int128 a) 365b7cd3db6SAvi Kivity { 3666046c620SPaolo Bonzini uint64_t lo = -a.lo; 3671edaeee0SRichard Henderson return int128_make128(lo, ~(uint64_t)a.hi + !lo); 368b7cd3db6SAvi Kivity } 369b7cd3db6SAvi Kivity 370b7cd3db6SAvi Kivity static inline Int128 int128_sub(Int128 a, Int128 b) 371b7cd3db6SAvi Kivity { 3721edaeee0SRichard Henderson return int128_make128(a.lo - b.lo, (uint64_t)a.hi - b.hi - (a.lo < b.lo)); 373b7cd3db6SAvi Kivity } 374b7cd3db6SAvi Kivity 375b7cd3db6SAvi Kivity static inline bool int128_nonneg(Int128 a) 376b7cd3db6SAvi Kivity { 377b7cd3db6SAvi Kivity return a.hi >= 0; 378b7cd3db6SAvi Kivity } 379b7cd3db6SAvi Kivity 380b7cd3db6SAvi Kivity static inline bool int128_eq(Int128 a, Int128 b) 381b7cd3db6SAvi Kivity { 382b7cd3db6SAvi Kivity return a.lo == b.lo && a.hi == b.hi; 383b7cd3db6SAvi Kivity } 384b7cd3db6SAvi Kivity 385b7cd3db6SAvi Kivity static inline bool int128_ne(Int128 a, Int128 b) 386b7cd3db6SAvi Kivity { 387b7cd3db6SAvi Kivity return !int128_eq(a, b); 388b7cd3db6SAvi Kivity } 389b7cd3db6SAvi Kivity 390b7cd3db6SAvi Kivity static inline bool int128_ge(Int128 a, Int128 b) 391b7cd3db6SAvi Kivity { 3926046c620SPaolo Bonzini return a.hi > b.hi || (a.hi == b.hi && a.lo >= b.lo); 393b7cd3db6SAvi Kivity } 394b7cd3db6SAvi Kivity 395*4724bbd2SLucas Mateus Castro (alqotel) static inline bool int128_uge(Int128 a, Int128 b) 396*4724bbd2SLucas Mateus Castro (alqotel) { 397*4724bbd2SLucas Mateus Castro (alqotel) return (uint64_t)a.hi > (uint64_t)b.hi || (a.hi == b.hi && a.lo >= b.lo); 398*4724bbd2SLucas Mateus Castro (alqotel) } 399*4724bbd2SLucas Mateus Castro (alqotel) 400b7cd3db6SAvi Kivity static inline bool int128_lt(Int128 a, Int128 b) 401b7cd3db6SAvi Kivity { 402b7cd3db6SAvi Kivity return !int128_ge(a, b); 403b7cd3db6SAvi Kivity } 404b7cd3db6SAvi Kivity 405*4724bbd2SLucas Mateus Castro (alqotel) static inline bool int128_ult(Int128 a, Int128 b) 406*4724bbd2SLucas Mateus Castro (alqotel) { 407*4724bbd2SLucas Mateus Castro (alqotel) return !int128_uge(a, b); 408*4724bbd2SLucas Mateus Castro (alqotel) } 409*4724bbd2SLucas Mateus Castro (alqotel) 410b7cd3db6SAvi Kivity static inline bool int128_le(Int128 a, Int128 b) 411b7cd3db6SAvi Kivity { 412b7cd3db6SAvi Kivity return int128_ge(b, a); 413b7cd3db6SAvi Kivity } 414b7cd3db6SAvi Kivity 415b7cd3db6SAvi Kivity static inline bool int128_gt(Int128 a, Int128 b) 416b7cd3db6SAvi Kivity { 417b7cd3db6SAvi Kivity return !int128_le(a, b); 418b7cd3db6SAvi Kivity } 419b7cd3db6SAvi Kivity 420b7cd3db6SAvi Kivity static inline bool int128_nz(Int128 a) 421b7cd3db6SAvi Kivity { 422b7cd3db6SAvi Kivity return a.lo || a.hi; 423b7cd3db6SAvi Kivity } 424b7cd3db6SAvi Kivity 425b7cd3db6SAvi Kivity static inline Int128 int128_min(Int128 a, Int128 b) 426b7cd3db6SAvi Kivity { 427b7cd3db6SAvi Kivity return int128_le(a, b) ? a : b; 428b7cd3db6SAvi Kivity } 429b7cd3db6SAvi Kivity 430b7cd3db6SAvi Kivity static inline Int128 int128_max(Int128 a, Int128 b) 431b7cd3db6SAvi Kivity { 432b7cd3db6SAvi Kivity return int128_ge(a, b) ? a : b; 433b7cd3db6SAvi Kivity } 434b7cd3db6SAvi Kivity 435b7cd3db6SAvi Kivity static inline void int128_addto(Int128 *a, Int128 b) 436b7cd3db6SAvi Kivity { 437b7cd3db6SAvi Kivity *a = int128_add(*a, b); 438b7cd3db6SAvi Kivity } 439b7cd3db6SAvi Kivity 440b7cd3db6SAvi Kivity static inline void int128_subfrom(Int128 *a, Int128 b) 441b7cd3db6SAvi Kivity { 442b7cd3db6SAvi Kivity *a = int128_sub(*a, b); 443b7cd3db6SAvi Kivity } 444b7cd3db6SAvi Kivity 4452484cd9cSMatheus Ferst static inline Int128 bswap128(Int128 a) 4462484cd9cSMatheus Ferst { 4472484cd9cSMatheus Ferst return int128_make128(bswap64(a.hi), bswap64(a.lo)); 4482484cd9cSMatheus Ferst } 4492484cd9cSMatheus Ferst 450*4724bbd2SLucas Mateus Castro (alqotel) static inline int clz128(Int128 a) 451*4724bbd2SLucas Mateus Castro (alqotel) { 452*4724bbd2SLucas Mateus Castro (alqotel) if (a.hi) { 453*4724bbd2SLucas Mateus Castro (alqotel) return __builtin_clzll(a.hi); 454*4724bbd2SLucas Mateus Castro (alqotel) } else { 455*4724bbd2SLucas Mateus Castro (alqotel) return (a.lo) ? __builtin_clzll(a.lo) + 64 : 128; 456*4724bbd2SLucas Mateus Castro (alqotel) } 457*4724bbd2SLucas Mateus Castro (alqotel) } 458*4724bbd2SLucas Mateus Castro (alqotel) 459e9d07601SFrédéric Pétrot Int128 int128_divu(Int128, Int128); 460e9d07601SFrédéric Pétrot Int128 int128_remu(Int128, Int128); 461e9d07601SFrédéric Pétrot Int128 int128_divs(Int128, Int128); 462e9d07601SFrédéric Pétrot Int128 int128_rems(Int128, Int128); 463e9d07601SFrédéric Pétrot 4640846beb3SRichard Henderson #endif /* CONFIG_INT128 */ 4652484cd9cSMatheus Ferst 4662484cd9cSMatheus Ferst static inline void bswap128s(Int128 *s) 4672484cd9cSMatheus Ferst { 4682484cd9cSMatheus Ferst *s = bswap128(*s); 4692484cd9cSMatheus Ferst } 4702484cd9cSMatheus Ferst 471e9d07601SFrédéric Pétrot #define UINT128_MAX int128_make128(~0LL, ~0LL) 472bea59230SMatheus Ferst #define INT128_MAX int128_make128(UINT64_MAX, INT64_MAX) 473bea59230SMatheus Ferst #define INT128_MIN int128_make128(0, INT64_MIN) 474e9d07601SFrédéric Pétrot 4750846beb3SRichard Henderson #endif /* INT128_H */ 476