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