qemu/include/qemu/int128.h
<<
>>
Prefs
   1#ifndef INT128_H
   2#define INT128_H
   3
   4
   5typedef struct Int128 Int128;
   6
   7struct Int128 {
   8    uint64_t lo;
   9    int64_t hi;
  10};
  11
  12static inline Int128 int128_make64(uint64_t a)
  13{
  14    return (Int128) { a, 0 };
  15}
  16
  17static inline uint64_t int128_get64(Int128 a)
  18{
  19    assert(!a.hi);
  20    return a.lo;
  21}
  22
  23static inline Int128 int128_zero(void)
  24{
  25    return int128_make64(0);
  26}
  27
  28static inline Int128 int128_one(void)
  29{
  30    return int128_make64(1);
  31}
  32
  33static inline Int128 int128_2_64(void)
  34{
  35    return (Int128) { 0, 1 };
  36}
  37
  38static inline Int128 int128_exts64(int64_t a)
  39{
  40    return (Int128) { .lo = a, .hi = (a < 0) ? -1 : 0 };
  41}
  42
  43static inline Int128 int128_and(Int128 a, Int128 b)
  44{
  45    return (Int128) { a.lo & b.lo, a.hi & b.hi };
  46}
  47
  48static inline Int128 int128_rshift(Int128 a, int n)
  49{
  50    int64_t h;
  51    if (!n) {
  52        return a;
  53    }
  54    h = a.hi >> (n & 63);
  55    if (n >= 64) {
  56        return (Int128) { h, h >> 63 };
  57    } else {
  58        return (Int128) { (a.lo >> n) | ((uint64_t)a.hi << (64 - n)), h };
  59    }
  60}
  61
  62static inline Int128 int128_add(Int128 a, Int128 b)
  63{
  64    uint64_t lo = a.lo + b.lo;
  65
  66    /* a.lo <= a.lo + b.lo < a.lo + k (k is the base, 2^64).  Hence,
  67     * a.lo + b.lo >= k implies 0 <= lo = a.lo + b.lo - k < a.lo.
  68     * Similarly, a.lo + b.lo < k implies a.lo <= lo = a.lo + b.lo < k.
  69     *
  70     * So the carry is lo < a.lo.
  71     */
  72    return (Int128) { lo, (uint64_t)a.hi + b.hi + (lo < a.lo) };
  73}
  74
  75static inline Int128 int128_neg(Int128 a)
  76{
  77    uint64_t lo = -a.lo;
  78    return (Int128) { lo, ~(uint64_t)a.hi + !lo };
  79}
  80
  81static inline Int128 int128_sub(Int128 a, Int128 b)
  82{
  83    return (Int128){ a.lo - b.lo, (uint64_t)a.hi - b.hi - (a.lo < b.lo) };
  84}
  85
  86static inline bool int128_nonneg(Int128 a)
  87{
  88    return a.hi >= 0;
  89}
  90
  91static inline bool int128_eq(Int128 a, Int128 b)
  92{
  93    return a.lo == b.lo && a.hi == b.hi;
  94}
  95
  96static inline bool int128_ne(Int128 a, Int128 b)
  97{
  98    return !int128_eq(a, b);
  99}
 100
 101static inline bool int128_ge(Int128 a, Int128 b)
 102{
 103    return a.hi > b.hi || (a.hi == b.hi && a.lo >= b.lo);
 104}
 105
 106static inline bool int128_lt(Int128 a, Int128 b)
 107{
 108    return !int128_ge(a, b);
 109}
 110
 111static inline bool int128_le(Int128 a, Int128 b)
 112{
 113    return int128_ge(b, a);
 114}
 115
 116static inline bool int128_gt(Int128 a, Int128 b)
 117{
 118    return !int128_le(a, b);
 119}
 120
 121static inline bool int128_nz(Int128 a)
 122{
 123    return a.lo || a.hi;
 124}
 125
 126static inline Int128 int128_min(Int128 a, Int128 b)
 127{
 128    return int128_le(a, b) ? a : b;
 129}
 130
 131static inline Int128 int128_max(Int128 a, Int128 b)
 132{
 133    return int128_ge(a, b) ? a : b;
 134}
 135
 136static inline void int128_addto(Int128 *a, Int128 b)
 137{
 138    *a = int128_add(*a, b);
 139}
 140
 141static inline void int128_subfrom(Int128 *a, Int128 b)
 142{
 143    *a = int128_sub(*a, b);
 144}
 145
 146#endif
 147