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_make128(uint64_t lo, uint64_t hi)
  15{
  16    return (__uint128_t)hi << 64 | lo;
  17}
  18
  19static inline uint64_t int128_get64(Int128 a)
  20{
  21    uint64_t r = a;
  22    assert(r == a);
  23    return r;
  24}
  25
  26static inline uint64_t int128_getlo(Int128 a)
  27{
  28    return a;
  29}
  30
  31static inline int64_t int128_gethi(Int128 a)
  32{
  33    return a >> 64;
  34}
  35
  36static inline Int128 int128_zero(void)
  37{
  38    return 0;
  39}
  40
  41static inline Int128 int128_one(void)
  42{
  43    return 1;
  44}
  45
  46static inline Int128 int128_2_64(void)
  47{
  48    return (Int128)1 << 64;
  49}
  50
  51static inline Int128 int128_exts64(int64_t a)
  52{
  53    return a;
  54}
  55
  56static inline Int128 int128_and(Int128 a, Int128 b)
  57{
  58    return a & b;
  59}
  60
  61static inline Int128 int128_rshift(Int128 a, int n)
  62{
  63    return a >> n;
  64}
  65
  66static inline Int128 int128_add(Int128 a, Int128 b)
  67{
  68    return a + b;
  69}
  70
  71static inline Int128 int128_neg(Int128 a)
  72{
  73    return -a;
  74}
  75
  76static inline Int128 int128_sub(Int128 a, Int128 b)
  77{
  78    return a - b;
  79}
  80
  81static inline bool int128_nonneg(Int128 a)
  82{
  83    return a >= 0;
  84}
  85
  86static inline bool int128_eq(Int128 a, Int128 b)
  87{
  88    return a == b;
  89}
  90
  91static inline bool int128_ne(Int128 a, Int128 b)
  92{
  93    return a != b;
  94}
  95
  96static inline bool int128_ge(Int128 a, Int128 b)
  97{
  98    return a >= b;
  99}
 100
 101static inline bool int128_lt(Int128 a, Int128 b)
 102{
 103    return a < b;
 104}
 105
 106static inline bool int128_le(Int128 a, Int128 b)
 107{
 108    return a <= b;
 109}
 110
 111static inline bool int128_gt(Int128 a, Int128 b)
 112{
 113    return a > b;
 114}
 115
 116static inline bool int128_nz(Int128 a)
 117{
 118    return a != 0;
 119}
 120
 121static inline Int128 int128_min(Int128 a, Int128 b)
 122{
 123    return a < b ? a : b;
 124}
 125
 126static inline Int128 int128_max(Int128 a, Int128 b)
 127{
 128    return a > b ? a : b;
 129}
 130
 131static inline void int128_addto(Int128 *a, Int128 b)
 132{
 133    *a += b;
 134}
 135
 136static inline void int128_subfrom(Int128 *a, Int128 b)
 137{
 138    *a -= b;
 139}
 140
 141static inline Int128 bswap128(Int128 a)
 142{
 143    return int128_make128(bswap64(int128_gethi(a)), bswap64(int128_getlo(a)));
 144}
 145
 146#else /* !CONFIG_INT128 */
 147
 148typedef struct Int128 Int128;
 149
 150struct Int128 {
 151    uint64_t lo;
 152    int64_t hi;
 153};
 154
 155static inline Int128 int128_make64(uint64_t a)
 156{
 157    return (Int128) { a, 0 };
 158}
 159
 160static inline Int128 int128_make128(uint64_t lo, uint64_t hi)
 161{
 162    return (Int128) { lo, hi };
 163}
 164
 165static inline uint64_t int128_get64(Int128 a)
 166{
 167    assert(!a.hi);
 168    return a.lo;
 169}
 170
 171static inline uint64_t int128_getlo(Int128 a)
 172{
 173    return a.lo;
 174}
 175
 176static inline int64_t int128_gethi(Int128 a)
 177{
 178    return a.hi;
 179}
 180
 181static inline Int128 int128_zero(void)
 182{
 183    return int128_make64(0);
 184}
 185
 186static inline Int128 int128_one(void)
 187{
 188    return int128_make64(1);
 189}
 190
 191static inline Int128 int128_2_64(void)
 192{
 193    return (Int128) { 0, 1 };
 194}
 195
 196static inline Int128 int128_exts64(int64_t a)
 197{
 198    return (Int128) { .lo = a, .hi = (a < 0) ? -1 : 0 };
 199}
 200
 201static inline Int128 int128_and(Int128 a, Int128 b)
 202{
 203    return (Int128) { a.lo & b.lo, a.hi & b.hi };
 204}
 205
 206static inline Int128 int128_rshift(Int128 a, int n)
 207{
 208    int64_t h;
 209    if (!n) {
 210        return a;
 211    }
 212    h = a.hi >> (n & 63);
 213    if (n >= 64) {
 214        return int128_make128(h, h >> 63);
 215    } else {
 216        return int128_make128((a.lo >> n) | ((uint64_t)a.hi << (64 - n)), h);
 217    }
 218}
 219
 220static inline Int128 int128_add(Int128 a, Int128 b)
 221{
 222    uint64_t lo = a.lo + b.lo;
 223
 224    /* a.lo <= a.lo + b.lo < a.lo + k (k is the base, 2^64).  Hence,
 225     * a.lo + b.lo >= k implies 0 <= lo = a.lo + b.lo - k < a.lo.
 226     * Similarly, a.lo + b.lo < k implies a.lo <= lo = a.lo + b.lo < k.
 227     *
 228     * So the carry is lo < a.lo.
 229     */
 230    return int128_make128(lo, (uint64_t)a.hi + b.hi + (lo < a.lo));
 231}
 232
 233static inline Int128 int128_neg(Int128 a)
 234{
 235    uint64_t lo = -a.lo;
 236    return int128_make128(lo, ~(uint64_t)a.hi + !lo);
 237}
 238
 239static inline Int128 int128_sub(Int128 a, Int128 b)
 240{
 241    return int128_make128(a.lo - b.lo, (uint64_t)a.hi - b.hi - (a.lo < b.lo));
 242}
 243
 244static inline bool int128_nonneg(Int128 a)
 245{
 246    return a.hi >= 0;
 247}
 248
 249static inline bool int128_eq(Int128 a, Int128 b)
 250{
 251    return a.lo == b.lo && a.hi == b.hi;
 252}
 253
 254static inline bool int128_ne(Int128 a, Int128 b)
 255{
 256    return !int128_eq(a, b);
 257}
 258
 259static inline bool int128_ge(Int128 a, Int128 b)
 260{
 261    return a.hi > b.hi || (a.hi == b.hi && a.lo >= b.lo);
 262}
 263
 264static inline bool int128_lt(Int128 a, Int128 b)
 265{
 266    return !int128_ge(a, b);
 267}
 268
 269static inline bool int128_le(Int128 a, Int128 b)
 270{
 271    return int128_ge(b, a);
 272}
 273
 274static inline bool int128_gt(Int128 a, Int128 b)
 275{
 276    return !int128_le(a, b);
 277}
 278
 279static inline bool int128_nz(Int128 a)
 280{
 281    return a.lo || a.hi;
 282}
 283
 284static inline Int128 int128_min(Int128 a, Int128 b)
 285{
 286    return int128_le(a, b) ? a : b;
 287}
 288
 289static inline Int128 int128_max(Int128 a, Int128 b)
 290{
 291    return int128_ge(a, b) ? a : b;
 292}
 293
 294static inline void int128_addto(Int128 *a, Int128 b)
 295{
 296    *a = int128_add(*a, b);
 297}
 298
 299static inline void int128_subfrom(Int128 *a, Int128 b)
 300{
 301    *a = int128_sub(*a, b);
 302}
 303
 304#endif /* CONFIG_INT128 */
 305#endif /* INT128_H */
 306