1 #ifndef INT128_H 2 #define INT128_H 3 4 #ifdef CONFIG_INT128 5 #include "qemu/bswap.h" 6 7 typedef __int128_t Int128; 8 9 static inline Int128 int128_make64(uint64_t a) 10 { 11 return a; 12 } 13 14 static inline Int128 int128_make128(uint64_t lo, uint64_t hi) 15 { 16 return (__uint128_t)hi << 64 | lo; 17 } 18 19 static inline uint64_t int128_get64(Int128 a) 20 { 21 uint64_t r = a; 22 assert(r == a); 23 return r; 24 } 25 26 static inline uint64_t int128_getlo(Int128 a) 27 { 28 return a; 29 } 30 31 static inline int64_t int128_gethi(Int128 a) 32 { 33 return a >> 64; 34 } 35 36 static inline Int128 int128_zero(void) 37 { 38 return 0; 39 } 40 41 static inline Int128 int128_one(void) 42 { 43 return 1; 44 } 45 46 static inline Int128 int128_2_64(void) 47 { 48 return (Int128)1 << 64; 49 } 50 51 static inline Int128 int128_exts64(int64_t a) 52 { 53 return a; 54 } 55 56 static inline Int128 int128_and(Int128 a, Int128 b) 57 { 58 return a & b; 59 } 60 61 static inline Int128 int128_rshift(Int128 a, int n) 62 { 63 return a >> n; 64 } 65 66 static inline Int128 int128_lshift(Int128 a, int n) 67 { 68 return a << n; 69 } 70 71 static inline Int128 int128_add(Int128 a, Int128 b) 72 { 73 return a + b; 74 } 75 76 static inline Int128 int128_neg(Int128 a) 77 { 78 return -a; 79 } 80 81 static inline Int128 int128_sub(Int128 a, Int128 b) 82 { 83 return a - b; 84 } 85 86 static inline bool int128_nonneg(Int128 a) 87 { 88 return a >= 0; 89 } 90 91 static inline bool int128_eq(Int128 a, Int128 b) 92 { 93 return a == b; 94 } 95 96 static inline bool int128_ne(Int128 a, Int128 b) 97 { 98 return a != b; 99 } 100 101 static inline bool int128_ge(Int128 a, Int128 b) 102 { 103 return a >= b; 104 } 105 106 static inline bool int128_lt(Int128 a, Int128 b) 107 { 108 return a < b; 109 } 110 111 static inline bool int128_le(Int128 a, Int128 b) 112 { 113 return a <= b; 114 } 115 116 static inline bool int128_gt(Int128 a, Int128 b) 117 { 118 return a > b; 119 } 120 121 static inline bool int128_nz(Int128 a) 122 { 123 return a != 0; 124 } 125 126 static inline Int128 int128_min(Int128 a, Int128 b) 127 { 128 return a < b ? a : b; 129 } 130 131 static inline Int128 int128_max(Int128 a, Int128 b) 132 { 133 return a > b ? a : b; 134 } 135 136 static inline void int128_addto(Int128 *a, Int128 b) 137 { 138 *a += b; 139 } 140 141 static inline void int128_subfrom(Int128 *a, Int128 b) 142 { 143 *a -= b; 144 } 145 146 static inline Int128 bswap128(Int128 a) 147 { 148 return int128_make128(bswap64(int128_gethi(a)), bswap64(int128_getlo(a))); 149 } 150 151 #else /* !CONFIG_INT128 */ 152 153 typedef struct Int128 Int128; 154 155 struct Int128 { 156 uint64_t lo; 157 int64_t hi; 158 }; 159 160 static inline Int128 int128_make64(uint64_t a) 161 { 162 return (Int128) { a, 0 }; 163 } 164 165 static inline Int128 int128_make128(uint64_t lo, uint64_t hi) 166 { 167 return (Int128) { lo, hi }; 168 } 169 170 static inline uint64_t int128_get64(Int128 a) 171 { 172 assert(!a.hi); 173 return a.lo; 174 } 175 176 static inline uint64_t int128_getlo(Int128 a) 177 { 178 return a.lo; 179 } 180 181 static inline int64_t int128_gethi(Int128 a) 182 { 183 return a.hi; 184 } 185 186 static inline Int128 int128_zero(void) 187 { 188 return int128_make64(0); 189 } 190 191 static inline Int128 int128_one(void) 192 { 193 return int128_make64(1); 194 } 195 196 static inline Int128 int128_2_64(void) 197 { 198 return (Int128) { 0, 1 }; 199 } 200 201 static inline Int128 int128_exts64(int64_t a) 202 { 203 return (Int128) { .lo = a, .hi = (a < 0) ? -1 : 0 }; 204 } 205 206 static inline Int128 int128_and(Int128 a, Int128 b) 207 { 208 return (Int128) { a.lo & b.lo, a.hi & b.hi }; 209 } 210 211 static inline Int128 int128_rshift(Int128 a, int n) 212 { 213 int64_t h; 214 if (!n) { 215 return a; 216 } 217 h = a.hi >> (n & 63); 218 if (n >= 64) { 219 return int128_make128(h, h >> 63); 220 } else { 221 return int128_make128((a.lo >> n) | ((uint64_t)a.hi << (64 - n)), h); 222 } 223 } 224 225 static inline Int128 int128_lshift(Int128 a, int n) 226 { 227 uint64_t l = a.lo << (n & 63); 228 if (n >= 64) { 229 return int128_make128(0, l); 230 } else if (n > 0) { 231 return int128_make128(l, (a.hi << n) | (a.lo >> (64 - n))); 232 } 233 return a; 234 } 235 236 static inline Int128 int128_add(Int128 a, Int128 b) 237 { 238 uint64_t lo = a.lo + b.lo; 239 240 /* a.lo <= a.lo + b.lo < a.lo + k (k is the base, 2^64). Hence, 241 * a.lo + b.lo >= k implies 0 <= lo = a.lo + b.lo - k < a.lo. 242 * Similarly, a.lo + b.lo < k implies a.lo <= lo = a.lo + b.lo < k. 243 * 244 * So the carry is lo < a.lo. 245 */ 246 return int128_make128(lo, (uint64_t)a.hi + b.hi + (lo < a.lo)); 247 } 248 249 static inline Int128 int128_neg(Int128 a) 250 { 251 uint64_t lo = -a.lo; 252 return int128_make128(lo, ~(uint64_t)a.hi + !lo); 253 } 254 255 static inline Int128 int128_sub(Int128 a, Int128 b) 256 { 257 return int128_make128(a.lo - b.lo, (uint64_t)a.hi - b.hi - (a.lo < b.lo)); 258 } 259 260 static inline bool int128_nonneg(Int128 a) 261 { 262 return a.hi >= 0; 263 } 264 265 static inline bool int128_eq(Int128 a, Int128 b) 266 { 267 return a.lo == b.lo && a.hi == b.hi; 268 } 269 270 static inline bool int128_ne(Int128 a, Int128 b) 271 { 272 return !int128_eq(a, b); 273 } 274 275 static inline bool int128_ge(Int128 a, Int128 b) 276 { 277 return a.hi > b.hi || (a.hi == b.hi && a.lo >= b.lo); 278 } 279 280 static inline bool int128_lt(Int128 a, Int128 b) 281 { 282 return !int128_ge(a, b); 283 } 284 285 static inline bool int128_le(Int128 a, Int128 b) 286 { 287 return int128_ge(b, a); 288 } 289 290 static inline bool int128_gt(Int128 a, Int128 b) 291 { 292 return !int128_le(a, b); 293 } 294 295 static inline bool int128_nz(Int128 a) 296 { 297 return a.lo || a.hi; 298 } 299 300 static inline Int128 int128_min(Int128 a, Int128 b) 301 { 302 return int128_le(a, b) ? a : b; 303 } 304 305 static inline Int128 int128_max(Int128 a, Int128 b) 306 { 307 return int128_ge(a, b) ? a : b; 308 } 309 310 static inline void int128_addto(Int128 *a, Int128 b) 311 { 312 *a = int128_add(*a, b); 313 } 314 315 static inline void int128_subfrom(Int128 *a, Int128 b) 316 { 317 *a = int128_sub(*a, b); 318 } 319 320 #endif /* CONFIG_INT128 */ 321 #endif /* INT128_H */ 322