1 #ifndef INT128_H 2 #define INT128_H 3 4 #include "qemu/bswap.h" 5 6 #ifdef CONFIG_INT128 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_makes64(int64_t a) 15 { 16 return a; 17 } 18 19 static inline Int128 int128_make128(uint64_t lo, uint64_t hi) 20 { 21 return (__uint128_t)hi << 64 | lo; 22 } 23 24 static inline uint64_t int128_get64(Int128 a) 25 { 26 uint64_t r = a; 27 assert(r == a); 28 return r; 29 } 30 31 static inline uint64_t int128_getlo(Int128 a) 32 { 33 return a; 34 } 35 36 static inline int64_t int128_gethi(Int128 a) 37 { 38 return a >> 64; 39 } 40 41 static inline Int128 int128_zero(void) 42 { 43 return 0; 44 } 45 46 static inline Int128 int128_one(void) 47 { 48 return 1; 49 } 50 51 static inline Int128 int128_2_64(void) 52 { 53 return (Int128)1 << 64; 54 } 55 56 static inline Int128 int128_exts64(int64_t a) 57 { 58 return a; 59 } 60 61 static inline Int128 int128_not(Int128 a) 62 { 63 return ~a; 64 } 65 66 static inline Int128 int128_and(Int128 a, Int128 b) 67 { 68 return a & b; 69 } 70 71 static inline Int128 int128_or(Int128 a, Int128 b) 72 { 73 return a | b; 74 } 75 76 static inline Int128 int128_xor(Int128 a, Int128 b) 77 { 78 return a ^ b; 79 } 80 81 static inline Int128 int128_rshift(Int128 a, int n) 82 { 83 return a >> n; 84 } 85 86 static inline Int128 int128_lshift(Int128 a, int n) 87 { 88 return a << n; 89 } 90 91 static inline Int128 int128_add(Int128 a, Int128 b) 92 { 93 return a + b; 94 } 95 96 static inline Int128 int128_neg(Int128 a) 97 { 98 return -a; 99 } 100 101 static inline Int128 int128_sub(Int128 a, Int128 b) 102 { 103 return a - b; 104 } 105 106 static inline bool int128_nonneg(Int128 a) 107 { 108 return a >= 0; 109 } 110 111 static inline bool int128_eq(Int128 a, Int128 b) 112 { 113 return a == b; 114 } 115 116 static inline bool int128_ne(Int128 a, Int128 b) 117 { 118 return a != b; 119 } 120 121 static inline bool int128_ge(Int128 a, Int128 b) 122 { 123 return a >= b; 124 } 125 126 static inline bool int128_lt(Int128 a, Int128 b) 127 { 128 return a < b; 129 } 130 131 static inline bool int128_le(Int128 a, Int128 b) 132 { 133 return a <= b; 134 } 135 136 static inline bool int128_gt(Int128 a, Int128 b) 137 { 138 return a > b; 139 } 140 141 static inline bool int128_nz(Int128 a) 142 { 143 return a != 0; 144 } 145 146 static inline Int128 int128_min(Int128 a, Int128 b) 147 { 148 return a < b ? a : b; 149 } 150 151 static inline Int128 int128_max(Int128 a, Int128 b) 152 { 153 return a > b ? a : b; 154 } 155 156 static inline void int128_addto(Int128 *a, Int128 b) 157 { 158 *a += b; 159 } 160 161 static inline void int128_subfrom(Int128 *a, Int128 b) 162 { 163 *a -= b; 164 } 165 166 static inline Int128 bswap128(Int128 a) 167 { 168 #if __has_builtin(__builtin_bswap128) 169 return __builtin_bswap128(a); 170 #else 171 return int128_make128(bswap64(int128_gethi(a)), bswap64(int128_getlo(a))); 172 #endif 173 } 174 175 static inline Int128 int128_divu(Int128 a, Int128 b) 176 { 177 return (__uint128_t)a / (__uint128_t)b; 178 } 179 180 static inline Int128 int128_remu(Int128 a, Int128 b) 181 { 182 return (__uint128_t)a % (__uint128_t)b; 183 } 184 185 static inline Int128 int128_divs(Int128 a, Int128 b) 186 { 187 return a / b; 188 } 189 190 static inline Int128 int128_rems(Int128 a, Int128 b) 191 { 192 return a % b; 193 } 194 195 #else /* !CONFIG_INT128 */ 196 197 typedef struct Int128 Int128; 198 199 /* 200 * We guarantee that the in-memory byte representation of an 201 * Int128 is that of a host-endian-order 128-bit integer 202 * (whether using this struct or the __int128_t version of the type). 203 * Some code using this type relies on this (eg when copying it into 204 * guest memory or a gdb protocol buffer, or by using Int128 in 205 * a union with other integer types). 206 */ 207 struct Int128 { 208 #ifdef HOST_WORDS_BIGENDIAN 209 int64_t hi; 210 uint64_t lo; 211 #else 212 uint64_t lo; 213 int64_t hi; 214 #endif 215 }; 216 217 static inline Int128 int128_make64(uint64_t a) 218 { 219 return (Int128) { .lo = a, .hi = 0 }; 220 } 221 222 static inline Int128 int128_makes64(int64_t a) 223 { 224 return (Int128) { .lo = a, .hi = a >> 63 }; 225 } 226 227 static inline Int128 int128_make128(uint64_t lo, uint64_t hi) 228 { 229 return (Int128) { .lo = lo, .hi = hi }; 230 } 231 232 static inline uint64_t int128_get64(Int128 a) 233 { 234 assert(!a.hi); 235 return a.lo; 236 } 237 238 static inline uint64_t int128_getlo(Int128 a) 239 { 240 return a.lo; 241 } 242 243 static inline int64_t int128_gethi(Int128 a) 244 { 245 return a.hi; 246 } 247 248 static inline Int128 int128_zero(void) 249 { 250 return int128_make64(0); 251 } 252 253 static inline Int128 int128_one(void) 254 { 255 return int128_make64(1); 256 } 257 258 static inline Int128 int128_2_64(void) 259 { 260 return int128_make128(0, 1); 261 } 262 263 static inline Int128 int128_exts64(int64_t a) 264 { 265 return int128_make128(a, (a < 0) ? -1 : 0); 266 } 267 268 static inline Int128 int128_not(Int128 a) 269 { 270 return int128_make128(~a.lo, ~a.hi); 271 } 272 273 static inline Int128 int128_and(Int128 a, Int128 b) 274 { 275 return int128_make128(a.lo & b.lo, a.hi & b.hi); 276 } 277 278 static inline Int128 int128_or(Int128 a, Int128 b) 279 { 280 return int128_make128(a.lo | b.lo, a.hi | b.hi); 281 } 282 283 static inline Int128 int128_xor(Int128 a, Int128 b) 284 { 285 return int128_make128(a.lo ^ b.lo, a.hi ^ b.hi); 286 } 287 288 static inline Int128 int128_rshift(Int128 a, int n) 289 { 290 int64_t h; 291 if (!n) { 292 return a; 293 } 294 h = a.hi >> (n & 63); 295 if (n >= 64) { 296 return int128_make128(h, h >> 63); 297 } else { 298 return int128_make128((a.lo >> n) | ((uint64_t)a.hi << (64 - n)), h); 299 } 300 } 301 302 static inline Int128 int128_lshift(Int128 a, int n) 303 { 304 uint64_t l = a.lo << (n & 63); 305 if (n >= 64) { 306 return int128_make128(0, l); 307 } else if (n > 0) { 308 return int128_make128(l, (a.hi << n) | (a.lo >> (64 - n))); 309 } 310 return a; 311 } 312 313 static inline Int128 int128_add(Int128 a, Int128 b) 314 { 315 uint64_t lo = a.lo + b.lo; 316 317 /* a.lo <= a.lo + b.lo < a.lo + k (k is the base, 2^64). Hence, 318 * a.lo + b.lo >= k implies 0 <= lo = a.lo + b.lo - k < a.lo. 319 * Similarly, a.lo + b.lo < k implies a.lo <= lo = a.lo + b.lo < k. 320 * 321 * So the carry is lo < a.lo. 322 */ 323 return int128_make128(lo, (uint64_t)a.hi + b.hi + (lo < a.lo)); 324 } 325 326 static inline Int128 int128_neg(Int128 a) 327 { 328 uint64_t lo = -a.lo; 329 return int128_make128(lo, ~(uint64_t)a.hi + !lo); 330 } 331 332 static inline Int128 int128_sub(Int128 a, Int128 b) 333 { 334 return int128_make128(a.lo - b.lo, (uint64_t)a.hi - b.hi - (a.lo < b.lo)); 335 } 336 337 static inline bool int128_nonneg(Int128 a) 338 { 339 return a.hi >= 0; 340 } 341 342 static inline bool int128_eq(Int128 a, Int128 b) 343 { 344 return a.lo == b.lo && a.hi == b.hi; 345 } 346 347 static inline bool int128_ne(Int128 a, Int128 b) 348 { 349 return !int128_eq(a, b); 350 } 351 352 static inline bool int128_ge(Int128 a, Int128 b) 353 { 354 return a.hi > b.hi || (a.hi == b.hi && a.lo >= b.lo); 355 } 356 357 static inline bool int128_lt(Int128 a, Int128 b) 358 { 359 return !int128_ge(a, b); 360 } 361 362 static inline bool int128_le(Int128 a, Int128 b) 363 { 364 return int128_ge(b, a); 365 } 366 367 static inline bool int128_gt(Int128 a, Int128 b) 368 { 369 return !int128_le(a, b); 370 } 371 372 static inline bool int128_nz(Int128 a) 373 { 374 return a.lo || a.hi; 375 } 376 377 static inline Int128 int128_min(Int128 a, Int128 b) 378 { 379 return int128_le(a, b) ? a : b; 380 } 381 382 static inline Int128 int128_max(Int128 a, Int128 b) 383 { 384 return int128_ge(a, b) ? a : b; 385 } 386 387 static inline void int128_addto(Int128 *a, Int128 b) 388 { 389 *a = int128_add(*a, b); 390 } 391 392 static inline void int128_subfrom(Int128 *a, Int128 b) 393 { 394 *a = int128_sub(*a, b); 395 } 396 397 static inline Int128 bswap128(Int128 a) 398 { 399 return int128_make128(bswap64(a.hi), bswap64(a.lo)); 400 } 401 402 Int128 int128_divu(Int128, Int128); 403 Int128 int128_remu(Int128, Int128); 404 Int128 int128_divs(Int128, Int128); 405 Int128 int128_rems(Int128, Int128); 406 407 #endif /* CONFIG_INT128 */ 408 409 static inline void bswap128s(Int128 *s) 410 { 411 *s = bswap128(*s); 412 } 413 414 #define UINT128_MAX int128_make128(~0LL, ~0LL) 415 416 #endif /* INT128_H */ 417