qemu/include/qemu/int128.h
<<
>>
Prefs
   1#ifndef INT128_H
   2#define INT128_H
   3
   4#ifdef CONFIG_INT128
   5#include "qemu/bswap.h"
   6
   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_and(Int128 a, Int128 b)
  62{
  63    return a & b;
  64}
  65
  66static inline Int128 int128_or(Int128 a, Int128 b)
  67{
  68    return a | b;
  69}
  70
  71static inline Int128 int128_rshift(Int128 a, int n)
  72{
  73    return a >> n;
  74}
  75
  76static inline Int128 int128_lshift(Int128 a, int n)
  77{
  78    return a << n;
  79}
  80
  81static inline Int128 int128_add(Int128 a, Int128 b)
  82{
  83    return a + b;
  84}
  85
  86static inline Int128 int128_neg(Int128 a)
  87{
  88    return -a;
  89}
  90
  91static inline Int128 int128_sub(Int128 a, Int128 b)
  92{
  93    return a - b;
  94}
  95
  96static inline bool int128_nonneg(Int128 a)
  97{
  98    return a >= 0;
  99}
 100
 101static inline bool int128_eq(Int128 a, Int128 b)
 102{
 103    return a == b;
 104}
 105
 106static inline bool int128_ne(Int128 a, Int128 b)
 107{
 108    return a != b;
 109}
 110
 111static inline bool int128_ge(Int128 a, Int128 b)
 112{
 113    return a >= b;
 114}
 115
 116static inline bool int128_lt(Int128 a, Int128 b)
 117{
 118    return a < b;
 119}
 120
 121static inline bool int128_le(Int128 a, Int128 b)
 122{
 123    return a <= b;
 124}
 125
 126static inline bool int128_gt(Int128 a, Int128 b)
 127{
 128    return a > b;
 129}
 130
 131static inline bool int128_nz(Int128 a)
 132{
 133    return a != 0;
 134}
 135
 136static inline Int128 int128_min(Int128 a, Int128 b)
 137{
 138    return a < b ? a : b;
 139}
 140
 141static inline Int128 int128_max(Int128 a, Int128 b)
 142{
 143    return a > b ? a : b;
 144}
 145
 146static inline void int128_addto(Int128 *a, Int128 b)
 147{
 148    *a += b;
 149}
 150
 151static inline void int128_subfrom(Int128 *a, Int128 b)
 152{
 153    *a -= b;
 154}
 155
 156static inline Int128 bswap128(Int128 a)
 157{
 158    return int128_make128(bswap64(int128_gethi(a)), bswap64(int128_getlo(a)));
 159}
 160
 161#else /* !CONFIG_INT128 */
 162
 163typedef struct Int128 Int128;
 164
 165struct Int128 {
 166    uint64_t lo;
 167    int64_t hi;
 168};
 169
 170static inline Int128 int128_make64(uint64_t a)
 171{
 172    return (Int128) { a, 0 };
 173}
 174
 175static inline Int128 int128_makes64(int64_t a)
 176{
 177    return (Int128) { a, a >> 63 };
 178}
 179
 180static inline Int128 int128_make128(uint64_t lo, uint64_t hi)
 181{
 182    return (Int128) { lo, hi };
 183}
 184
 185static inline uint64_t int128_get64(Int128 a)
 186{
 187    assert(!a.hi);
 188    return a.lo;
 189}
 190
 191static inline uint64_t int128_getlo(Int128 a)
 192{
 193    return a.lo;
 194}
 195
 196static inline int64_t int128_gethi(Int128 a)
 197{
 198    return a.hi;
 199}
 200
 201static inline Int128 int128_zero(void)
 202{
 203    return int128_make64(0);
 204}
 205
 206static inline Int128 int128_one(void)
 207{
 208    return int128_make64(1);
 209}
 210
 211static inline Int128 int128_2_64(void)
 212{
 213    return (Int128) { 0, 1 };
 214}
 215
 216static inline Int128 int128_exts64(int64_t a)
 217{
 218    return (Int128) { .lo = a, .hi = (a < 0) ? -1 : 0 };
 219}
 220
 221static inline Int128 int128_and(Int128 a, Int128 b)
 222{
 223    return (Int128) { a.lo & b.lo, a.hi & b.hi };
 224}
 225
 226static inline Int128 int128_or(Int128 a, Int128 b)
 227{
 228    return (Int128) { a.lo | b.lo, a.hi | b.hi };
 229}
 230
 231static inline Int128 int128_rshift(Int128 a, int n)
 232{
 233    int64_t h;
 234    if (!n) {
 235        return a;
 236    }
 237    h = a.hi >> (n & 63);
 238    if (n >= 64) {
 239        return int128_make128(h, h >> 63);
 240    } else {
 241        return int128_make128((a.lo >> n) | ((uint64_t)a.hi << (64 - n)), h);
 242    }
 243}
 244
 245static inline Int128 int128_lshift(Int128 a, int n)
 246{
 247    uint64_t l = a.lo << (n & 63);
 248    if (n >= 64) {
 249        return int128_make128(0, l);
 250    } else if (n > 0) {
 251        return int128_make128(l, (a.hi << n) | (a.lo >> (64 - n)));
 252    }
 253    return a;
 254}
 255
 256static inline Int128 int128_add(Int128 a, Int128 b)
 257{
 258    uint64_t lo = a.lo + b.lo;
 259
 260    /* a.lo <= a.lo + b.lo < a.lo + k (k is the base, 2^64).  Hence,
 261     * a.lo + b.lo >= k implies 0 <= lo = a.lo + b.lo - k < a.lo.
 262     * Similarly, a.lo + b.lo < k implies a.lo <= lo = a.lo + b.lo < k.
 263     *
 264     * So the carry is lo < a.lo.
 265     */
 266    return int128_make128(lo, (uint64_t)a.hi + b.hi + (lo < a.lo));
 267}
 268
 269static inline Int128 int128_neg(Int128 a)
 270{
 271    uint64_t lo = -a.lo;
 272    return int128_make128(lo, ~(uint64_t)a.hi + !lo);
 273}
 274
 275static inline Int128 int128_sub(Int128 a, Int128 b)
 276{
 277    return int128_make128(a.lo - b.lo, (uint64_t)a.hi - b.hi - (a.lo < b.lo));
 278}
 279
 280static inline bool int128_nonneg(Int128 a)
 281{
 282    return a.hi >= 0;
 283}
 284
 285static inline bool int128_eq(Int128 a, Int128 b)
 286{
 287    return a.lo == b.lo && a.hi == b.hi;
 288}
 289
 290static inline bool int128_ne(Int128 a, Int128 b)
 291{
 292    return !int128_eq(a, b);
 293}
 294
 295static inline bool int128_ge(Int128 a, Int128 b)
 296{
 297    return a.hi > b.hi || (a.hi == b.hi && a.lo >= b.lo);
 298}
 299
 300static inline bool int128_lt(Int128 a, Int128 b)
 301{
 302    return !int128_ge(a, b);
 303}
 304
 305static inline bool int128_le(Int128 a, Int128 b)
 306{
 307    return int128_ge(b, a);
 308}
 309
 310static inline bool int128_gt(Int128 a, Int128 b)
 311{
 312    return !int128_le(a, b);
 313}
 314
 315static inline bool int128_nz(Int128 a)
 316{
 317    return a.lo || a.hi;
 318}
 319
 320static inline Int128 int128_min(Int128 a, Int128 b)
 321{
 322    return int128_le(a, b) ? a : b;
 323}
 324
 325static inline Int128 int128_max(Int128 a, Int128 b)
 326{
 327    return int128_ge(a, b) ? a : b;
 328}
 329
 330static inline void int128_addto(Int128 *a, Int128 b)
 331{
 332    *a = int128_add(*a, b);
 333}
 334
 335static inline void int128_subfrom(Int128 *a, Int128 b)
 336{
 337    *a = int128_sub(*a, b);
 338}
 339
 340#endif /* CONFIG_INT128 */
 341#endif /* INT128_H */
 342