1b7cd3db6SAvi Kivity #ifndef INT128_H 2b7cd3db6SAvi Kivity #define INT128_H 3b7cd3db6SAvi Kivity 4b7cd3db6SAvi Kivity typedef struct Int128 Int128; 5b7cd3db6SAvi Kivity 6b7cd3db6SAvi Kivity struct Int128 { 7b7cd3db6SAvi Kivity uint64_t lo; 8b7cd3db6SAvi Kivity int64_t hi; 9b7cd3db6SAvi Kivity }; 10b7cd3db6SAvi Kivity 11b7cd3db6SAvi Kivity static inline Int128 int128_make64(uint64_t a) 12b7cd3db6SAvi Kivity { 13b7cd3db6SAvi Kivity return (Int128) { a, 0 }; 14b7cd3db6SAvi Kivity } 15b7cd3db6SAvi Kivity 16b7cd3db6SAvi Kivity static inline uint64_t int128_get64(Int128 a) 17b7cd3db6SAvi Kivity { 18b7cd3db6SAvi Kivity assert(!a.hi); 19b7cd3db6SAvi Kivity return a.lo; 20b7cd3db6SAvi Kivity } 21b7cd3db6SAvi Kivity 22b7cd3db6SAvi Kivity static inline Int128 int128_zero(void) 23b7cd3db6SAvi Kivity { 24b7cd3db6SAvi Kivity return int128_make64(0); 25b7cd3db6SAvi Kivity } 26b7cd3db6SAvi Kivity 27b7cd3db6SAvi Kivity static inline Int128 int128_one(void) 28b7cd3db6SAvi Kivity { 29b7cd3db6SAvi Kivity return int128_make64(1); 30b7cd3db6SAvi Kivity } 31b7cd3db6SAvi Kivity 32b7cd3db6SAvi Kivity static inline Int128 int128_2_64(void) 33b7cd3db6SAvi Kivity { 34b7cd3db6SAvi Kivity return (Int128) { 0, 1 }; 35b7cd3db6SAvi Kivity } 36b7cd3db6SAvi Kivity 37*052e87b0SPaolo Bonzini static inline Int128 int128_and(Int128 a, Int128 b) 38*052e87b0SPaolo Bonzini { 39*052e87b0SPaolo Bonzini return (Int128) { a.lo & b.lo, a.hi & b.hi }; 40*052e87b0SPaolo Bonzini } 41*052e87b0SPaolo Bonzini 42*052e87b0SPaolo Bonzini static inline Int128 int128_rshift(Int128 a, int n) 43*052e87b0SPaolo Bonzini { 44*052e87b0SPaolo Bonzini int64_t h; 45*052e87b0SPaolo Bonzini if (!n) { 46*052e87b0SPaolo Bonzini return a; 47*052e87b0SPaolo Bonzini } 48*052e87b0SPaolo Bonzini h = a.hi >> (n & 63); 49*052e87b0SPaolo Bonzini if (n >= 64) { 50*052e87b0SPaolo Bonzini return (Int128) { h, h >> 63 }; 51*052e87b0SPaolo Bonzini } else { 52*052e87b0SPaolo Bonzini return (Int128) { (a.lo >> n) | (a.hi << (64 - n)), h }; 53*052e87b0SPaolo Bonzini } 54*052e87b0SPaolo Bonzini } 55*052e87b0SPaolo Bonzini 56b7cd3db6SAvi Kivity static inline Int128 int128_add(Int128 a, Int128 b) 57b7cd3db6SAvi Kivity { 58b7cd3db6SAvi Kivity Int128 r = { a.lo + b.lo, a.hi + b.hi }; 59b7cd3db6SAvi Kivity r.hi += (r.lo < a.lo) || (r.lo < b.lo); 60b7cd3db6SAvi Kivity return r; 61b7cd3db6SAvi Kivity } 62b7cd3db6SAvi Kivity 63b7cd3db6SAvi Kivity static inline Int128 int128_neg(Int128 a) 64b7cd3db6SAvi Kivity { 65b7cd3db6SAvi Kivity a.lo = ~a.lo; 66b7cd3db6SAvi Kivity a.hi = ~a.hi; 67b7cd3db6SAvi Kivity return int128_add(a, int128_one()); 68b7cd3db6SAvi Kivity } 69b7cd3db6SAvi Kivity 70b7cd3db6SAvi Kivity static inline Int128 int128_sub(Int128 a, Int128 b) 71b7cd3db6SAvi Kivity { 72b7cd3db6SAvi Kivity return int128_add(a, int128_neg(b)); 73b7cd3db6SAvi Kivity } 74b7cd3db6SAvi Kivity 75b7cd3db6SAvi Kivity static inline bool int128_nonneg(Int128 a) 76b7cd3db6SAvi Kivity { 77b7cd3db6SAvi Kivity return a.hi >= 0; 78b7cd3db6SAvi Kivity } 79b7cd3db6SAvi Kivity 80b7cd3db6SAvi Kivity static inline bool int128_eq(Int128 a, Int128 b) 81b7cd3db6SAvi Kivity { 82b7cd3db6SAvi Kivity return a.lo == b.lo && a.hi == b.hi; 83b7cd3db6SAvi Kivity } 84b7cd3db6SAvi Kivity 85b7cd3db6SAvi Kivity static inline bool int128_ne(Int128 a, Int128 b) 86b7cd3db6SAvi Kivity { 87b7cd3db6SAvi Kivity return !int128_eq(a, b); 88b7cd3db6SAvi Kivity } 89b7cd3db6SAvi Kivity 90b7cd3db6SAvi Kivity static inline bool int128_ge(Int128 a, Int128 b) 91b7cd3db6SAvi Kivity { 92b7cd3db6SAvi Kivity return int128_nonneg(int128_sub(a, b)); 93b7cd3db6SAvi Kivity } 94b7cd3db6SAvi Kivity 95b7cd3db6SAvi Kivity static inline bool int128_lt(Int128 a, Int128 b) 96b7cd3db6SAvi Kivity { 97b7cd3db6SAvi Kivity return !int128_ge(a, b); 98b7cd3db6SAvi Kivity } 99b7cd3db6SAvi Kivity 100b7cd3db6SAvi Kivity static inline bool int128_le(Int128 a, Int128 b) 101b7cd3db6SAvi Kivity { 102b7cd3db6SAvi Kivity return int128_ge(b, a); 103b7cd3db6SAvi Kivity } 104b7cd3db6SAvi Kivity 105b7cd3db6SAvi Kivity static inline bool int128_gt(Int128 a, Int128 b) 106b7cd3db6SAvi Kivity { 107b7cd3db6SAvi Kivity return !int128_le(a, b); 108b7cd3db6SAvi Kivity } 109b7cd3db6SAvi Kivity 110b7cd3db6SAvi Kivity static inline bool int128_nz(Int128 a) 111b7cd3db6SAvi Kivity { 112b7cd3db6SAvi Kivity return a.lo || a.hi; 113b7cd3db6SAvi Kivity } 114b7cd3db6SAvi Kivity 115b7cd3db6SAvi Kivity static inline Int128 int128_min(Int128 a, Int128 b) 116b7cd3db6SAvi Kivity { 117b7cd3db6SAvi Kivity return int128_le(a, b) ? a : b; 118b7cd3db6SAvi Kivity } 119b7cd3db6SAvi Kivity 120b7cd3db6SAvi Kivity static inline Int128 int128_max(Int128 a, Int128 b) 121b7cd3db6SAvi Kivity { 122b7cd3db6SAvi Kivity return int128_ge(a, b) ? a : b; 123b7cd3db6SAvi Kivity } 124b7cd3db6SAvi Kivity 125b7cd3db6SAvi Kivity static inline void int128_addto(Int128 *a, Int128 b) 126b7cd3db6SAvi Kivity { 127b7cd3db6SAvi Kivity *a = int128_add(*a, b); 128b7cd3db6SAvi Kivity } 129b7cd3db6SAvi Kivity 130b7cd3db6SAvi Kivity static inline void int128_subfrom(Int128 *a, Int128 b) 131b7cd3db6SAvi Kivity { 132b7cd3db6SAvi Kivity *a = int128_sub(*a, b); 133b7cd3db6SAvi Kivity } 134b7cd3db6SAvi Kivity 135b7cd3db6SAvi Kivity #endif 136