1b7cd3db6SAvi Kivity #ifndef INT128_H 2b7cd3db6SAvi Kivity #define INT128_H 3b7cd3db6SAvi Kivity 4*0846beb3SRichard Henderson #ifdef CONFIG_INT128 5*0846beb3SRichard Henderson 6*0846beb3SRichard Henderson typedef __int128_t Int128; 7*0846beb3SRichard Henderson 8*0846beb3SRichard Henderson static inline Int128 int128_make64(uint64_t a) 9*0846beb3SRichard Henderson { 10*0846beb3SRichard Henderson return a; 11*0846beb3SRichard Henderson } 12*0846beb3SRichard Henderson 13*0846beb3SRichard Henderson static inline uint64_t int128_get64(Int128 a) 14*0846beb3SRichard Henderson { 15*0846beb3SRichard Henderson uint64_t r = a; 16*0846beb3SRichard Henderson assert(r == a); 17*0846beb3SRichard Henderson return r; 18*0846beb3SRichard Henderson } 19*0846beb3SRichard Henderson 20*0846beb3SRichard Henderson static inline uint64_t int128_getlo(Int128 a) 21*0846beb3SRichard Henderson { 22*0846beb3SRichard Henderson return a; 23*0846beb3SRichard Henderson } 24*0846beb3SRichard Henderson 25*0846beb3SRichard Henderson static inline int64_t int128_gethi(Int128 a) 26*0846beb3SRichard Henderson { 27*0846beb3SRichard Henderson return a >> 64; 28*0846beb3SRichard Henderson } 29*0846beb3SRichard Henderson 30*0846beb3SRichard Henderson static inline Int128 int128_zero(void) 31*0846beb3SRichard Henderson { 32*0846beb3SRichard Henderson return 0; 33*0846beb3SRichard Henderson } 34*0846beb3SRichard Henderson 35*0846beb3SRichard Henderson static inline Int128 int128_one(void) 36*0846beb3SRichard Henderson { 37*0846beb3SRichard Henderson return 1; 38*0846beb3SRichard Henderson } 39*0846beb3SRichard Henderson 40*0846beb3SRichard Henderson static inline Int128 int128_2_64(void) 41*0846beb3SRichard Henderson { 42*0846beb3SRichard Henderson return (Int128)1 << 64; 43*0846beb3SRichard Henderson } 44*0846beb3SRichard Henderson 45*0846beb3SRichard Henderson static inline Int128 int128_exts64(int64_t a) 46*0846beb3SRichard Henderson { 47*0846beb3SRichard Henderson return a; 48*0846beb3SRichard Henderson } 49*0846beb3SRichard Henderson 50*0846beb3SRichard Henderson static inline Int128 int128_and(Int128 a, Int128 b) 51*0846beb3SRichard Henderson { 52*0846beb3SRichard Henderson return a & b; 53*0846beb3SRichard Henderson } 54*0846beb3SRichard Henderson 55*0846beb3SRichard Henderson static inline Int128 int128_rshift(Int128 a, int n) 56*0846beb3SRichard Henderson { 57*0846beb3SRichard Henderson return a >> n; 58*0846beb3SRichard Henderson } 59*0846beb3SRichard Henderson 60*0846beb3SRichard Henderson static inline Int128 int128_add(Int128 a, Int128 b) 61*0846beb3SRichard Henderson { 62*0846beb3SRichard Henderson return a + b; 63*0846beb3SRichard Henderson } 64*0846beb3SRichard Henderson 65*0846beb3SRichard Henderson static inline Int128 int128_neg(Int128 a) 66*0846beb3SRichard Henderson { 67*0846beb3SRichard Henderson return -a; 68*0846beb3SRichard Henderson } 69*0846beb3SRichard Henderson 70*0846beb3SRichard Henderson static inline Int128 int128_sub(Int128 a, Int128 b) 71*0846beb3SRichard Henderson { 72*0846beb3SRichard Henderson return a - b; 73*0846beb3SRichard Henderson } 74*0846beb3SRichard Henderson 75*0846beb3SRichard Henderson static inline bool int128_nonneg(Int128 a) 76*0846beb3SRichard Henderson { 77*0846beb3SRichard Henderson return a >= 0; 78*0846beb3SRichard Henderson } 79*0846beb3SRichard Henderson 80*0846beb3SRichard Henderson static inline bool int128_eq(Int128 a, Int128 b) 81*0846beb3SRichard Henderson { 82*0846beb3SRichard Henderson return a == b; 83*0846beb3SRichard Henderson } 84*0846beb3SRichard Henderson 85*0846beb3SRichard Henderson static inline bool int128_ne(Int128 a, Int128 b) 86*0846beb3SRichard Henderson { 87*0846beb3SRichard Henderson return a != b; 88*0846beb3SRichard Henderson } 89*0846beb3SRichard Henderson 90*0846beb3SRichard Henderson static inline bool int128_ge(Int128 a, Int128 b) 91*0846beb3SRichard Henderson { 92*0846beb3SRichard Henderson return a >= b; 93*0846beb3SRichard Henderson } 94*0846beb3SRichard Henderson 95*0846beb3SRichard Henderson static inline bool int128_lt(Int128 a, Int128 b) 96*0846beb3SRichard Henderson { 97*0846beb3SRichard Henderson return a < b; 98*0846beb3SRichard Henderson } 99*0846beb3SRichard Henderson 100*0846beb3SRichard Henderson static inline bool int128_le(Int128 a, Int128 b) 101*0846beb3SRichard Henderson { 102*0846beb3SRichard Henderson return a <= b; 103*0846beb3SRichard Henderson } 104*0846beb3SRichard Henderson 105*0846beb3SRichard Henderson static inline bool int128_gt(Int128 a, Int128 b) 106*0846beb3SRichard Henderson { 107*0846beb3SRichard Henderson return a > b; 108*0846beb3SRichard Henderson } 109*0846beb3SRichard Henderson 110*0846beb3SRichard Henderson static inline bool int128_nz(Int128 a) 111*0846beb3SRichard Henderson { 112*0846beb3SRichard Henderson return a != 0; 113*0846beb3SRichard Henderson } 114*0846beb3SRichard Henderson 115*0846beb3SRichard Henderson static inline Int128 int128_min(Int128 a, Int128 b) 116*0846beb3SRichard Henderson { 117*0846beb3SRichard Henderson return a < b ? a : b; 118*0846beb3SRichard Henderson } 119*0846beb3SRichard Henderson 120*0846beb3SRichard Henderson static inline Int128 int128_max(Int128 a, Int128 b) 121*0846beb3SRichard Henderson { 122*0846beb3SRichard Henderson return a > b ? a : b; 123*0846beb3SRichard Henderson } 124*0846beb3SRichard Henderson 125*0846beb3SRichard Henderson static inline void int128_addto(Int128 *a, Int128 b) 126*0846beb3SRichard Henderson { 127*0846beb3SRichard Henderson *a += b; 128*0846beb3SRichard Henderson } 129*0846beb3SRichard Henderson 130*0846beb3SRichard Henderson static inline void int128_subfrom(Int128 *a, Int128 b) 131*0846beb3SRichard Henderson { 132*0846beb3SRichard Henderson *a -= b; 133*0846beb3SRichard Henderson } 134*0846beb3SRichard Henderson 135*0846beb3SRichard Henderson #else /* !CONFIG_INT128 */ 1366046c620SPaolo Bonzini 137b7cd3db6SAvi Kivity typedef struct Int128 Int128; 138b7cd3db6SAvi Kivity 139b7cd3db6SAvi Kivity struct Int128 { 140b7cd3db6SAvi Kivity uint64_t lo; 141b7cd3db6SAvi Kivity int64_t hi; 142b7cd3db6SAvi Kivity }; 143b7cd3db6SAvi Kivity 144b7cd3db6SAvi Kivity static inline Int128 int128_make64(uint64_t a) 145b7cd3db6SAvi Kivity { 146b7cd3db6SAvi Kivity return (Int128) { a, 0 }; 147b7cd3db6SAvi Kivity } 148b7cd3db6SAvi Kivity 149b7cd3db6SAvi Kivity static inline uint64_t int128_get64(Int128 a) 150b7cd3db6SAvi Kivity { 151b7cd3db6SAvi Kivity assert(!a.hi); 152b7cd3db6SAvi Kivity return a.lo; 153b7cd3db6SAvi Kivity } 154b7cd3db6SAvi Kivity 155258dfaaaSRichard Henderson static inline uint64_t int128_getlo(Int128 a) 156258dfaaaSRichard Henderson { 157258dfaaaSRichard Henderson return a.lo; 158258dfaaaSRichard Henderson } 159258dfaaaSRichard Henderson 160258dfaaaSRichard Henderson static inline int64_t int128_gethi(Int128 a) 161258dfaaaSRichard Henderson { 162258dfaaaSRichard Henderson return a.hi; 163258dfaaaSRichard Henderson } 164258dfaaaSRichard Henderson 165b7cd3db6SAvi Kivity static inline Int128 int128_zero(void) 166b7cd3db6SAvi Kivity { 167b7cd3db6SAvi Kivity return int128_make64(0); 168b7cd3db6SAvi Kivity } 169b7cd3db6SAvi Kivity 170b7cd3db6SAvi Kivity static inline Int128 int128_one(void) 171b7cd3db6SAvi Kivity { 172b7cd3db6SAvi Kivity return int128_make64(1); 173b7cd3db6SAvi Kivity } 174b7cd3db6SAvi Kivity 175b7cd3db6SAvi Kivity static inline Int128 int128_2_64(void) 176b7cd3db6SAvi Kivity { 177b7cd3db6SAvi Kivity return (Int128) { 0, 1 }; 178b7cd3db6SAvi Kivity } 179b7cd3db6SAvi Kivity 18012e1129bSAlexey Kardashevskiy static inline Int128 int128_exts64(int64_t a) 18112e1129bSAlexey Kardashevskiy { 18212e1129bSAlexey Kardashevskiy return (Int128) { .lo = a, .hi = (a < 0) ? -1 : 0 }; 18312e1129bSAlexey Kardashevskiy } 18412e1129bSAlexey Kardashevskiy 185052e87b0SPaolo Bonzini static inline Int128 int128_and(Int128 a, Int128 b) 186052e87b0SPaolo Bonzini { 187052e87b0SPaolo Bonzini return (Int128) { a.lo & b.lo, a.hi & b.hi }; 188052e87b0SPaolo Bonzini } 189052e87b0SPaolo Bonzini 190052e87b0SPaolo Bonzini static inline Int128 int128_rshift(Int128 a, int n) 191052e87b0SPaolo Bonzini { 192052e87b0SPaolo Bonzini int64_t h; 193052e87b0SPaolo Bonzini if (!n) { 194052e87b0SPaolo Bonzini return a; 195052e87b0SPaolo Bonzini } 196052e87b0SPaolo Bonzini h = a.hi >> (n & 63); 197052e87b0SPaolo Bonzini if (n >= 64) { 198052e87b0SPaolo Bonzini return (Int128) { h, h >> 63 }; 199052e87b0SPaolo Bonzini } else { 200423d00c8SPeter Maydell return (Int128) { (a.lo >> n) | ((uint64_t)a.hi << (64 - n)), h }; 201052e87b0SPaolo Bonzini } 202052e87b0SPaolo Bonzini } 203052e87b0SPaolo Bonzini 204b7cd3db6SAvi Kivity static inline Int128 int128_add(Int128 a, Int128 b) 205b7cd3db6SAvi Kivity { 2066046c620SPaolo Bonzini uint64_t lo = a.lo + b.lo; 2076046c620SPaolo Bonzini 2086046c620SPaolo Bonzini /* a.lo <= a.lo + b.lo < a.lo + k (k is the base, 2^64). Hence, 2096046c620SPaolo Bonzini * a.lo + b.lo >= k implies 0 <= lo = a.lo + b.lo - k < a.lo. 2106046c620SPaolo Bonzini * Similarly, a.lo + b.lo < k implies a.lo <= lo = a.lo + b.lo < k. 2116046c620SPaolo Bonzini * 2126046c620SPaolo Bonzini * So the carry is lo < a.lo. 2136046c620SPaolo Bonzini */ 2146046c620SPaolo Bonzini return (Int128) { lo, (uint64_t)a.hi + b.hi + (lo < a.lo) }; 215b7cd3db6SAvi Kivity } 216b7cd3db6SAvi Kivity 217b7cd3db6SAvi Kivity static inline Int128 int128_neg(Int128 a) 218b7cd3db6SAvi Kivity { 2196046c620SPaolo Bonzini uint64_t lo = -a.lo; 2206046c620SPaolo Bonzini return (Int128) { lo, ~(uint64_t)a.hi + !lo }; 221b7cd3db6SAvi Kivity } 222b7cd3db6SAvi Kivity 223b7cd3db6SAvi Kivity static inline Int128 int128_sub(Int128 a, Int128 b) 224b7cd3db6SAvi Kivity { 225423d00c8SPeter Maydell return (Int128){ a.lo - b.lo, (uint64_t)a.hi - b.hi - (a.lo < b.lo) }; 226b7cd3db6SAvi Kivity } 227b7cd3db6SAvi Kivity 228b7cd3db6SAvi Kivity static inline bool int128_nonneg(Int128 a) 229b7cd3db6SAvi Kivity { 230b7cd3db6SAvi Kivity return a.hi >= 0; 231b7cd3db6SAvi Kivity } 232b7cd3db6SAvi Kivity 233b7cd3db6SAvi Kivity static inline bool int128_eq(Int128 a, Int128 b) 234b7cd3db6SAvi Kivity { 235b7cd3db6SAvi Kivity return a.lo == b.lo && a.hi == b.hi; 236b7cd3db6SAvi Kivity } 237b7cd3db6SAvi Kivity 238b7cd3db6SAvi Kivity static inline bool int128_ne(Int128 a, Int128 b) 239b7cd3db6SAvi Kivity { 240b7cd3db6SAvi Kivity return !int128_eq(a, b); 241b7cd3db6SAvi Kivity } 242b7cd3db6SAvi Kivity 243b7cd3db6SAvi Kivity static inline bool int128_ge(Int128 a, Int128 b) 244b7cd3db6SAvi Kivity { 2456046c620SPaolo Bonzini return a.hi > b.hi || (a.hi == b.hi && a.lo >= b.lo); 246b7cd3db6SAvi Kivity } 247b7cd3db6SAvi Kivity 248b7cd3db6SAvi Kivity static inline bool int128_lt(Int128 a, Int128 b) 249b7cd3db6SAvi Kivity { 250b7cd3db6SAvi Kivity return !int128_ge(a, b); 251b7cd3db6SAvi Kivity } 252b7cd3db6SAvi Kivity 253b7cd3db6SAvi Kivity static inline bool int128_le(Int128 a, Int128 b) 254b7cd3db6SAvi Kivity { 255b7cd3db6SAvi Kivity return int128_ge(b, a); 256b7cd3db6SAvi Kivity } 257b7cd3db6SAvi Kivity 258b7cd3db6SAvi Kivity static inline bool int128_gt(Int128 a, Int128 b) 259b7cd3db6SAvi Kivity { 260b7cd3db6SAvi Kivity return !int128_le(a, b); 261b7cd3db6SAvi Kivity } 262b7cd3db6SAvi Kivity 263b7cd3db6SAvi Kivity static inline bool int128_nz(Int128 a) 264b7cd3db6SAvi Kivity { 265b7cd3db6SAvi Kivity return a.lo || a.hi; 266b7cd3db6SAvi Kivity } 267b7cd3db6SAvi Kivity 268b7cd3db6SAvi Kivity static inline Int128 int128_min(Int128 a, Int128 b) 269b7cd3db6SAvi Kivity { 270b7cd3db6SAvi Kivity return int128_le(a, b) ? a : b; 271b7cd3db6SAvi Kivity } 272b7cd3db6SAvi Kivity 273b7cd3db6SAvi Kivity static inline Int128 int128_max(Int128 a, Int128 b) 274b7cd3db6SAvi Kivity { 275b7cd3db6SAvi Kivity return int128_ge(a, b) ? a : b; 276b7cd3db6SAvi Kivity } 277b7cd3db6SAvi Kivity 278b7cd3db6SAvi Kivity static inline void int128_addto(Int128 *a, Int128 b) 279b7cd3db6SAvi Kivity { 280b7cd3db6SAvi Kivity *a = int128_add(*a, b); 281b7cd3db6SAvi Kivity } 282b7cd3db6SAvi Kivity 283b7cd3db6SAvi Kivity static inline void int128_subfrom(Int128 *a, Int128 b) 284b7cd3db6SAvi Kivity { 285b7cd3db6SAvi Kivity *a = int128_sub(*a, b); 286b7cd3db6SAvi Kivity } 287b7cd3db6SAvi Kivity 288*0846beb3SRichard Henderson #endif /* CONFIG_INT128 */ 289*0846beb3SRichard Henderson #endif /* INT128_H */ 290