qemu/include/qemu/int128.h
<<
>>
Prefs
   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)
  12typedef __int128_t Int128;
  13
  14static inline Int128 int128_make64(uint64_t a)
  15{
  16    return a;
  17}
  18
  19static inline Int128 int128_makes64(int64_t a)
  20{
  21    return a;
  22}
  23
  24static inline Int128 int128_make128(uint64_t lo, uint64_t hi)
  25{
  26    return (__uint128_t)hi << 64 | lo;
  27}
  28
  29static inline uint64_t int128_get64(Int128 a)
  30{
  31    uint64_t r = a;
  32    assert(r == a);
  33    return r;
  34}
  35
  36static inline uint64_t int128_getlo(Int128 a)
  37{
  38    return a;
  39}
  40
  41static inline int64_t int128_gethi(Int128 a)
  42{
  43    return a >> 64;
  44}
  45
  46static inline Int128 int128_zero(void)
  47{
  48    return 0;
  49}
  50
  51static inline Int128 int128_one(void)
  52{
  53    return 1;
  54}
  55
  56static inline Int128 int128_2_64(void)
  57{
  58    return (Int128)1 << 64;
  59}
  60
  61static inline Int128 int128_exts64(int64_t a)
  62{
  63    return a;
  64}
  65
  66static inline Int128 int128_not(Int128 a)
  67{
  68    return ~a;
  69}
  70
  71static inline Int128 int128_and(Int128 a, Int128 b)
  72{
  73    return a & b;
  74}
  75
  76static inline Int128 int128_or(Int128 a, Int128 b)
  77{
  78    return a | b;
  79}
  80
  81static inline Int128 int128_xor(Int128 a, Int128 b)
  82{
  83    return a ^ b;
  84}
  85
  86static inline Int128 int128_rshift(Int128 a, int n)
  87{
  88    return a >> n;
  89}
  90
  91static inline Int128 int128_urshift(Int128 a, int n)
  92{
  93    return (__uint128_t)a >> n;
  94}
  95
  96static inline Int128 int128_lshift(Int128 a, int n)
  97{
  98    return a << n;
  99}
 100
 101static inline Int128 int128_add(Int128 a, Int128 b)
 102{
 103    return a + b;
 104}
 105
 106static inline Int128 int128_neg(Int128 a)
 107{
 108    return -a;
 109}
 110
 111static inline Int128 int128_sub(Int128 a, Int128 b)
 112{
 113    return a - b;
 114}
 115
 116static inline bool int128_nonneg(Int128 a)
 117{
 118    return a >= 0;
 119}
 120
 121static inline bool int128_eq(Int128 a, Int128 b)
 122{
 123    return a == b;
 124}
 125
 126static inline bool int128_ne(Int128 a, Int128 b)
 127{
 128    return a != b;
 129}
 130
 131static inline bool int128_ge(Int128 a, Int128 b)
 132{
 133    return a >= b;
 134}
 135
 136static inline bool int128_uge(Int128 a, Int128 b)
 137{
 138    return ((__uint128_t)a) >= ((__uint128_t)b);
 139}
 140
 141static inline bool int128_lt(Int128 a, Int128 b)
 142{
 143    return a < b;
 144}
 145
 146static inline bool int128_ult(Int128 a, Int128 b)
 147{
 148    return (__uint128_t)a < (__uint128_t)b;
 149}
 150
 151static inline bool int128_le(Int128 a, Int128 b)
 152{
 153    return a <= b;
 154}
 155
 156static inline bool int128_gt(Int128 a, Int128 b)
 157{
 158    return a > b;
 159}
 160
 161static inline bool int128_nz(Int128 a)
 162{
 163    return a != 0;
 164}
 165
 166static inline Int128 int128_min(Int128 a, Int128 b)
 167{
 168    return a < b ? a : b;
 169}
 170
 171static inline Int128 int128_max(Int128 a, Int128 b)
 172{
 173    return a > b ? a : b;
 174}
 175
 176static inline void int128_addto(Int128 *a, Int128 b)
 177{
 178    *a += b;
 179}
 180
 181static inline void int128_subfrom(Int128 *a, Int128 b)
 182{
 183    *a -= b;
 184}
 185
 186static 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
 195static 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
 204static inline Int128 int128_divu(Int128 a, Int128 b)
 205{
 206    return (__uint128_t)a / (__uint128_t)b;
 207}
 208
 209static inline Int128 int128_remu(Int128 a, Int128 b)
 210{
 211    return (__uint128_t)a % (__uint128_t)b;
 212}
 213
 214static inline Int128 int128_divs(Int128 a, Int128 b)
 215{
 216    return a / b;
 217}
 218
 219static inline Int128 int128_rems(Int128 a, Int128 b)
 220{
 221    return a % b;
 222}
 223
 224#else /* !CONFIG_INT128 */
 225
 226typedef 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 */
 236struct 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
 246static inline Int128 int128_make64(uint64_t a)
 247{
 248    return (Int128) { .lo = a, .hi = 0 };
 249}
 250
 251static inline Int128 int128_makes64(int64_t a)
 252{
 253    return (Int128) { .lo = a, .hi = a >> 63 };
 254}
 255
 256static inline Int128 int128_make128(uint64_t lo, uint64_t hi)
 257{
 258    return (Int128) { .lo = lo, .hi = hi };
 259}
 260
 261static inline uint64_t int128_get64(Int128 a)
 262{
 263    assert(!a.hi);
 264    return a.lo;
 265}
 266
 267static inline uint64_t int128_getlo(Int128 a)
 268{
 269    return a.lo;
 270}
 271
 272static inline int64_t int128_gethi(Int128 a)
 273{
 274    return a.hi;
 275}
 276
 277static inline Int128 int128_zero(void)
 278{
 279    return int128_make64(0);
 280}
 281
 282static inline Int128 int128_one(void)
 283{
 284    return int128_make64(1);
 285}
 286
 287static inline Int128 int128_2_64(void)
 288{
 289    return int128_make128(0, 1);
 290}
 291
 292static inline Int128 int128_exts64(int64_t a)
 293{
 294    return int128_make128(a, (a < 0) ? -1 : 0);
 295}
 296
 297static inline Int128 int128_not(Int128 a)
 298{
 299    return int128_make128(~a.lo, ~a.hi);
 300}
 301
 302static inline Int128 int128_and(Int128 a, Int128 b)
 303{
 304    return int128_make128(a.lo & b.lo, a.hi & b.hi);
 305}
 306
 307static inline Int128 int128_or(Int128 a, Int128 b)
 308{
 309    return int128_make128(a.lo | b.lo, a.hi | b.hi);
 310}
 311
 312static inline Int128 int128_xor(Int128 a, Int128 b)
 313{
 314    return int128_make128(a.lo ^ b.lo, a.hi ^ b.hi);
 315}
 316
 317static 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
 331static 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
 345static 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
 356static 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
 369static 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
 375static 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
 380static inline bool int128_nonneg(Int128 a)
 381{
 382    return a.hi >= 0;
 383}
 384
 385static inline bool int128_eq(Int128 a, Int128 b)
 386{
 387    return a.lo == b.lo && a.hi == b.hi;
 388}
 389
 390static inline bool int128_ne(Int128 a, Int128 b)
 391{
 392    return !int128_eq(a, b);
 393}
 394
 395static 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
 400static 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
 405static inline bool int128_lt(Int128 a, Int128 b)
 406{
 407    return !int128_ge(a, b);
 408}
 409
 410static inline bool int128_ult(Int128 a, Int128 b)
 411{
 412    return !int128_uge(a, b);
 413}
 414
 415static inline bool int128_le(Int128 a, Int128 b)
 416{
 417    return int128_ge(b, a);
 418}
 419
 420static inline bool int128_gt(Int128 a, Int128 b)
 421{
 422    return !int128_le(a, b);
 423}
 424
 425static inline bool int128_nz(Int128 a)
 426{
 427    return a.lo || a.hi;
 428}
 429
 430static inline Int128 int128_min(Int128 a, Int128 b)
 431{
 432    return int128_le(a, b) ? a : b;
 433}
 434
 435static inline Int128 int128_max(Int128 a, Int128 b)
 436{
 437    return int128_ge(a, b) ? a : b;
 438}
 439
 440static inline void int128_addto(Int128 *a, Int128 b)
 441{
 442    *a = int128_add(*a, b);
 443}
 444
 445static inline void int128_subfrom(Int128 *a, Int128 b)
 446{
 447    *a = int128_sub(*a, b);
 448}
 449
 450static inline Int128 bswap128(Int128 a)
 451{
 452    return int128_make128(bswap64(a.hi), bswap64(a.lo));
 453}
 454
 455static 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
 464Int128 int128_divu(Int128, Int128);
 465Int128 int128_remu(Int128, Int128);
 466Int128 int128_divs(Int128, Int128);
 467Int128 int128_rems(Int128, Int128);
 468#endif /* CONFIG_INT128 && !CONFIG_TCG_INTERPRETER */
 469
 470static 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
 485typedef union {
 486    __uint128_t u;
 487    __int128_t i;
 488    Int128 s;
 489} Int128Alias __attribute__((transparent_union));
 490#else
 491typedef Int128 Int128Alias;
 492#endif /* CONFIG_INT128_TYPE */
 493
 494#endif /* INT128_H */
 495