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