1 #ifndef INT128_H 2 #define INT128_H 3 4 #include "qemu/bswap.h" 5 6 /* 7 * With TCI, we need to use libffi for interfacing with TCG helpers. 8 * But libffi does not support __int128_t, and therefore cannot pass 9 * or return values of this type, force use of the Int128 struct. 10 */ 11 #if defined(CONFIG_INT128) && !defined(CONFIG_TCG_INTERPRETER) 12 typedef __int128_t Int128; 13 14 static inline Int128 int128_make64(uint64_t a) 15 { 16 return a; 17 } 18 19 static inline Int128 int128_makes64(int64_t a) 20 { 21 return a; 22 } 23 24 static inline Int128 int128_make128(uint64_t lo, uint64_t hi) 25 { 26 return (__uint128_t)hi << 64 | lo; 27 } 28 29 static inline uint64_t int128_get64(Int128 a) 30 { 31 uint64_t r = a; 32 assert(r == a); 33 return r; 34 } 35 36 static inline uint64_t int128_getlo(Int128 a) 37 { 38 return a; 39 } 40 41 static inline int64_t int128_gethi(Int128 a) 42 { 43 return a >> 64; 44 } 45 46 static inline Int128 int128_zero(void) 47 { 48 return 0; 49 } 50 51 static inline Int128 int128_one(void) 52 { 53 return 1; 54 } 55 56 static inline Int128 int128_2_64(void) 57 { 58 return (Int128)1 << 64; 59 } 60 61 static inline Int128 int128_exts64(int64_t a) 62 { 63 return a; 64 } 65 66 static inline Int128 int128_not(Int128 a) 67 { 68 return ~a; 69 } 70 71 static inline Int128 int128_and(Int128 a, Int128 b) 72 { 73 return a & b; 74 } 75 76 static inline Int128 int128_or(Int128 a, Int128 b) 77 { 78 return a | b; 79 } 80 81 static inline Int128 int128_xor(Int128 a, Int128 b) 82 { 83 return a ^ b; 84 } 85 86 static inline Int128 int128_rshift(Int128 a, int n) 87 { 88 return a >> n; 89 } 90 91 static inline Int128 int128_urshift(Int128 a, int n) 92 { 93 return (__uint128_t)a >> n; 94 } 95 96 static inline Int128 int128_lshift(Int128 a, int n) 97 { 98 return a << n; 99 } 100 101 static inline Int128 int128_add(Int128 a, Int128 b) 102 { 103 return a + b; 104 } 105 106 static inline Int128 int128_neg(Int128 a) 107 { 108 return -a; 109 } 110 111 static inline Int128 int128_sub(Int128 a, Int128 b) 112 { 113 return a - b; 114 } 115 116 static inline bool int128_nonneg(Int128 a) 117 { 118 return a >= 0; 119 } 120 121 static inline bool int128_eq(Int128 a, Int128 b) 122 { 123 return a == b; 124 } 125 126 static inline bool int128_ne(Int128 a, Int128 b) 127 { 128 return a != b; 129 } 130 131 static inline bool int128_ge(Int128 a, Int128 b) 132 { 133 return a >= b; 134 } 135 136 static inline bool int128_uge(Int128 a, Int128 b) 137 { 138 return ((__uint128_t)a) >= ((__uint128_t)b); 139 } 140 141 static inline bool int128_lt(Int128 a, Int128 b) 142 { 143 return a < b; 144 } 145 146 static inline bool int128_ult(Int128 a, Int128 b) 147 { 148 return (__uint128_t)a < (__uint128_t)b; 149 } 150 151 static inline bool int128_le(Int128 a, Int128 b) 152 { 153 return a <= b; 154 } 155 156 static inline bool int128_gt(Int128 a, Int128 b) 157 { 158 return a > b; 159 } 160 161 static inline bool int128_nz(Int128 a) 162 { 163 return a != 0; 164 } 165 166 static inline Int128 int128_min(Int128 a, Int128 b) 167 { 168 return a < b ? a : b; 169 } 170 171 static inline Int128 int128_max(Int128 a, Int128 b) 172 { 173 return a > b ? a : b; 174 } 175 176 static inline void int128_addto(Int128 *a, Int128 b) 177 { 178 *a += b; 179 } 180 181 static inline void int128_subfrom(Int128 *a, Int128 b) 182 { 183 *a -= b; 184 } 185 186 static inline Int128 bswap128(Int128 a) 187 { 188 #if __has_builtin(__builtin_bswap128) 189 return __builtin_bswap128(a); 190 #else 191 return int128_make128(bswap64(int128_gethi(a)), bswap64(int128_getlo(a))); 192 #endif 193 } 194 195 static inline int clz128(Int128 a) 196 { 197 if (a >> 64) { 198 return __builtin_clzll(a >> 64); 199 } else { 200 return (a) ? __builtin_clzll((uint64_t)a) + 64 : 128; 201 } 202 } 203 204 static inline Int128 int128_divu(Int128 a, Int128 b) 205 { 206 return (__uint128_t)a / (__uint128_t)b; 207 } 208 209 static inline Int128 int128_remu(Int128 a, Int128 b) 210 { 211 return (__uint128_t)a % (__uint128_t)b; 212 } 213 214 static inline Int128 int128_divs(Int128 a, Int128 b) 215 { 216 return a / b; 217 } 218 219 static inline Int128 int128_rems(Int128 a, Int128 b) 220 { 221 return a % b; 222 } 223 224 #else /* !CONFIG_INT128 */ 225 226 typedef struct Int128 Int128; 227 228 /* 229 * We guarantee that the in-memory byte representation of an 230 * Int128 is that of a host-endian-order 128-bit integer 231 * (whether using this struct or the __int128_t version of the type). 232 * Some code using this type relies on this (eg when copying it into 233 * guest memory or a gdb protocol buffer, or by using Int128 in 234 * a union with other integer types). 235 */ 236 struct Int128 { 237 #if HOST_BIG_ENDIAN 238 int64_t hi; 239 uint64_t lo; 240 #else 241 uint64_t lo; 242 int64_t hi; 243 #endif 244 }; 245 246 static inline Int128 int128_make64(uint64_t a) 247 { 248 return (Int128) { .lo = a, .hi = 0 }; 249 } 250 251 static inline Int128 int128_makes64(int64_t a) 252 { 253 return (Int128) { .lo = a, .hi = a >> 63 }; 254 } 255 256 static inline Int128 int128_make128(uint64_t lo, uint64_t hi) 257 { 258 return (Int128) { .lo = lo, .hi = hi }; 259 } 260 261 static inline uint64_t int128_get64(Int128 a) 262 { 263 assert(!a.hi); 264 return a.lo; 265 } 266 267 static inline uint64_t int128_getlo(Int128 a) 268 { 269 return a.lo; 270 } 271 272 static inline int64_t int128_gethi(Int128 a) 273 { 274 return a.hi; 275 } 276 277 static inline Int128 int128_zero(void) 278 { 279 return int128_make64(0); 280 } 281 282 static inline Int128 int128_one(void) 283 { 284 return int128_make64(1); 285 } 286 287 static inline Int128 int128_2_64(void) 288 { 289 return int128_make128(0, 1); 290 } 291 292 static inline Int128 int128_exts64(int64_t a) 293 { 294 return int128_make128(a, (a < 0) ? -1 : 0); 295 } 296 297 static inline Int128 int128_not(Int128 a) 298 { 299 return int128_make128(~a.lo, ~a.hi); 300 } 301 302 static inline Int128 int128_and(Int128 a, Int128 b) 303 { 304 return int128_make128(a.lo & b.lo, a.hi & b.hi); 305 } 306 307 static inline Int128 int128_or(Int128 a, Int128 b) 308 { 309 return int128_make128(a.lo | b.lo, a.hi | b.hi); 310 } 311 312 static inline Int128 int128_xor(Int128 a, Int128 b) 313 { 314 return int128_make128(a.lo ^ b.lo, a.hi ^ b.hi); 315 } 316 317 static inline Int128 int128_rshift(Int128 a, int n) 318 { 319 int64_t h; 320 if (!n) { 321 return a; 322 } 323 h = a.hi >> (n & 63); 324 if (n >= 64) { 325 return int128_make128(h, h >> 63); 326 } else { 327 return int128_make128((a.lo >> n) | ((uint64_t)a.hi << (64 - n)), h); 328 } 329 } 330 331 static inline Int128 int128_urshift(Int128 a, int n) 332 { 333 uint64_t h = a.hi; 334 if (!n) { 335 return a; 336 } 337 h = h >> (n & 63); 338 if (n >= 64) { 339 return int128_make64(h); 340 } else { 341 return int128_make128((a.lo >> n) | ((uint64_t)a.hi << (64 - n)), h); 342 } 343 } 344 345 static inline Int128 int128_lshift(Int128 a, int n) 346 { 347 uint64_t l = a.lo << (n & 63); 348 if (n >= 64) { 349 return int128_make128(0, l); 350 } else if (n > 0) { 351 return int128_make128(l, (a.hi << n) | (a.lo >> (64 - n))); 352 } 353 return a; 354 } 355 356 static inline Int128 int128_add(Int128 a, Int128 b) 357 { 358 uint64_t lo = a.lo + b.lo; 359 360 /* a.lo <= a.lo + b.lo < a.lo + k (k is the base, 2^64). Hence, 361 * a.lo + b.lo >= k implies 0 <= lo = a.lo + b.lo - k < a.lo. 362 * Similarly, a.lo + b.lo < k implies a.lo <= lo = a.lo + b.lo < k. 363 * 364 * So the carry is lo < a.lo. 365 */ 366 return int128_make128(lo, (uint64_t)a.hi + b.hi + (lo < a.lo)); 367 } 368 369 static inline Int128 int128_neg(Int128 a) 370 { 371 uint64_t lo = -a.lo; 372 return int128_make128(lo, ~(uint64_t)a.hi + !lo); 373 } 374 375 static inline Int128 int128_sub(Int128 a, Int128 b) 376 { 377 return int128_make128(a.lo - b.lo, (uint64_t)a.hi - b.hi - (a.lo < b.lo)); 378 } 379 380 static inline bool int128_nonneg(Int128 a) 381 { 382 return a.hi >= 0; 383 } 384 385 static inline bool int128_eq(Int128 a, Int128 b) 386 { 387 return a.lo == b.lo && a.hi == b.hi; 388 } 389 390 static inline bool int128_ne(Int128 a, Int128 b) 391 { 392 return !int128_eq(a, b); 393 } 394 395 static inline bool int128_ge(Int128 a, Int128 b) 396 { 397 return a.hi > b.hi || (a.hi == b.hi && a.lo >= b.lo); 398 } 399 400 static inline bool int128_uge(Int128 a, Int128 b) 401 { 402 return (uint64_t)a.hi > (uint64_t)b.hi || (a.hi == b.hi && a.lo >= b.lo); 403 } 404 405 static inline bool int128_lt(Int128 a, Int128 b) 406 { 407 return !int128_ge(a, b); 408 } 409 410 static inline bool int128_ult(Int128 a, Int128 b) 411 { 412 return !int128_uge(a, b); 413 } 414 415 static inline bool int128_le(Int128 a, Int128 b) 416 { 417 return int128_ge(b, a); 418 } 419 420 static inline bool int128_gt(Int128 a, Int128 b) 421 { 422 return !int128_le(a, b); 423 } 424 425 static inline bool int128_nz(Int128 a) 426 { 427 return a.lo || a.hi; 428 } 429 430 static inline Int128 int128_min(Int128 a, Int128 b) 431 { 432 return int128_le(a, b) ? a : b; 433 } 434 435 static inline Int128 int128_max(Int128 a, Int128 b) 436 { 437 return int128_ge(a, b) ? a : b; 438 } 439 440 static inline void int128_addto(Int128 *a, Int128 b) 441 { 442 *a = int128_add(*a, b); 443 } 444 445 static inline void int128_subfrom(Int128 *a, Int128 b) 446 { 447 *a = int128_sub(*a, b); 448 } 449 450 static inline Int128 bswap128(Int128 a) 451 { 452 return int128_make128(bswap64(a.hi), bswap64(a.lo)); 453 } 454 455 static inline int clz128(Int128 a) 456 { 457 if (a.hi) { 458 return __builtin_clzll(a.hi); 459 } else { 460 return (a.lo) ? __builtin_clzll(a.lo) + 64 : 128; 461 } 462 } 463 464 Int128 int128_divu(Int128, Int128); 465 Int128 int128_remu(Int128, Int128); 466 Int128 int128_divs(Int128, Int128); 467 Int128 int128_rems(Int128, Int128); 468 #endif /* CONFIG_INT128 && !CONFIG_TCG_INTERPRETER */ 469 470 static inline void bswap128s(Int128 *s) 471 { 472 *s = bswap128(*s); 473 } 474 475 #define UINT128_MAX int128_make128(~0LL, ~0LL) 476 #define INT128_MAX int128_make128(UINT64_MAX, INT64_MAX) 477 #define INT128_MIN int128_make128(0, INT64_MIN) 478 479 /* 480 * When compiler supports a 128-bit type, define a combination of 481 * a possible structure and the native types. Ease parameter passing 482 * via use of the transparent union extension. 483 */ 484 #ifdef CONFIG_INT128_TYPE 485 typedef union { 486 __uint128_t u; 487 __int128_t i; 488 Int128 s; 489 } Int128Alias __attribute__((transparent_union)); 490 #else 491 typedef Int128 Int128Alias; 492 #endif /* CONFIG_INT128_TYPE */ 493 494 #endif /* INT128_H */ 495