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