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_lshift(Int128 a, int n)
  87{
  88    return a << n;
  89}
  90
  91static inline Int128 int128_add(Int128 a, Int128 b)
  92{
  93    return a + b;
  94}
  95
  96static inline Int128 int128_neg(Int128 a)
  97{
  98    return -a;
  99}
 100
 101static inline Int128 int128_sub(Int128 a, Int128 b)
 102{
 103    return a - b;
 104}
 105
 106static inline bool int128_nonneg(Int128 a)
 107{
 108    return a >= 0;
 109}
 110
 111static inline bool int128_eq(Int128 a, Int128 b)
 112{
 113    return a == b;
 114}
 115
 116static inline bool int128_ne(Int128 a, Int128 b)
 117{
 118    return a != b;
 119}
 120
 121static inline bool int128_ge(Int128 a, Int128 b)
 122{
 123    return a >= b;
 124}
 125
 126static inline bool int128_lt(Int128 a, Int128 b)
 127{
 128    return a < b;
 129}
 130
 131static inline bool int128_le(Int128 a, Int128 b)
 132{
 133    return a <= b;
 134}
 135
 136static inline bool int128_gt(Int128 a, Int128 b)
 137{
 138    return a > b;
 139}
 140
 141static inline bool int128_nz(Int128 a)
 142{
 143    return a != 0;
 144}
 145
 146static inline Int128 int128_min(Int128 a, Int128 b)
 147{
 148    return a < b ? a : b;
 149}
 150
 151static inline Int128 int128_max(Int128 a, Int128 b)
 152{
 153    return a > b ? a : b;
 154}
 155
 156static inline void int128_addto(Int128 *a, Int128 b)
 157{
 158    *a += b;
 159}
 160
 161static inline void int128_subfrom(Int128 *a, Int128 b)
 162{
 163    *a -= b;
 164}
 165
 166static inline Int128 bswap128(Int128 a)
 167{
 168#if __has_builtin(__builtin_bswap128)
 169    return __builtin_bswap128(a);
 170#else
 171    return int128_make128(bswap64(int128_gethi(a)), bswap64(int128_getlo(a)));
 172#endif
 173}
 174
 175#else /* !CONFIG_INT128 */
 176
 177typedef struct Int128 Int128;
 178
 179/*
 180 * We guarantee that the in-memory byte representation of an
 181 * Int128 is that of a host-endian-order 128-bit integer
 182 * (whether using this struct or the __int128_t version of the type).
 183 * Some code using this type relies on this (eg when copying it into
 184 * guest memory or a gdb protocol buffer, or by using Int128 in
 185 * a union with other integer types).
 186 */
 187struct Int128 {
 188#ifdef HOST_WORDS_BIGENDIAN
 189    int64_t hi;
 190    uint64_t lo;
 191#else
 192    uint64_t lo;
 193    int64_t hi;
 194#endif
 195};
 196
 197static inline Int128 int128_make64(uint64_t a)
 198{
 199    return (Int128) { .lo = a, .hi = 0 };
 200}
 201
 202static inline Int128 int128_makes64(int64_t a)
 203{
 204    return (Int128) { .lo = a, .hi = a >> 63 };
 205}
 206
 207static inline Int128 int128_make128(uint64_t lo, uint64_t hi)
 208{
 209    return (Int128) { .lo = lo, .hi = hi };
 210}
 211
 212static inline uint64_t int128_get64(Int128 a)
 213{
 214    assert(!a.hi);
 215    return a.lo;
 216}
 217
 218static inline uint64_t int128_getlo(Int128 a)
 219{
 220    return a.lo;
 221}
 222
 223static inline int64_t int128_gethi(Int128 a)
 224{
 225    return a.hi;
 226}
 227
 228static inline Int128 int128_zero(void)
 229{
 230    return int128_make64(0);
 231}
 232
 233static inline Int128 int128_one(void)
 234{
 235    return int128_make64(1);
 236}
 237
 238static inline Int128 int128_2_64(void)
 239{
 240    return int128_make128(0, 1);
 241}
 242
 243static inline Int128 int128_exts64(int64_t a)
 244{
 245    return int128_make128(a, (a < 0) ? -1 : 0);
 246}
 247
 248static inline Int128 int128_not(Int128 a)
 249{
 250    return int128_make128(~a.lo, ~a.hi);
 251}
 252
 253static inline Int128 int128_and(Int128 a, Int128 b)
 254{
 255    return int128_make128(a.lo & b.lo, a.hi & b.hi);
 256}
 257
 258static inline Int128 int128_or(Int128 a, Int128 b)
 259{
 260    return int128_make128(a.lo | b.lo, a.hi | b.hi);
 261}
 262
 263static inline Int128 int128_xor(Int128 a, Int128 b)
 264{
 265    return int128_make128(a.lo ^ b.lo, a.hi ^ b.hi);
 266}
 267
 268static inline Int128 int128_rshift(Int128 a, int n)
 269{
 270    int64_t h;
 271    if (!n) {
 272        return a;
 273    }
 274    h = a.hi >> (n & 63);
 275    if (n >= 64) {
 276        return int128_make128(h, h >> 63);
 277    } else {
 278        return int128_make128((a.lo >> n) | ((uint64_t)a.hi << (64 - n)), h);
 279    }
 280}
 281
 282static inline Int128 int128_lshift(Int128 a, int n)
 283{
 284    uint64_t l = a.lo << (n & 63);
 285    if (n >= 64) {
 286        return int128_make128(0, l);
 287    } else if (n > 0) {
 288        return int128_make128(l, (a.hi << n) | (a.lo >> (64 - n)));
 289    }
 290    return a;
 291}
 292
 293static inline Int128 int128_add(Int128 a, Int128 b)
 294{
 295    uint64_t lo = a.lo + b.lo;
 296
 297    /* a.lo <= a.lo + b.lo < a.lo + k (k is the base, 2^64).  Hence,
 298     * a.lo + b.lo >= k implies 0 <= lo = a.lo + b.lo - k < a.lo.
 299     * Similarly, a.lo + b.lo < k implies a.lo <= lo = a.lo + b.lo < k.
 300     *
 301     * So the carry is lo < a.lo.
 302     */
 303    return int128_make128(lo, (uint64_t)a.hi + b.hi + (lo < a.lo));
 304}
 305
 306static inline Int128 int128_neg(Int128 a)
 307{
 308    uint64_t lo = -a.lo;
 309    return int128_make128(lo, ~(uint64_t)a.hi + !lo);
 310}
 311
 312static inline Int128 int128_sub(Int128 a, Int128 b)
 313{
 314    return int128_make128(a.lo - b.lo, (uint64_t)a.hi - b.hi - (a.lo < b.lo));
 315}
 316
 317static inline bool int128_nonneg(Int128 a)
 318{
 319    return a.hi >= 0;
 320}
 321
 322static inline bool int128_eq(Int128 a, Int128 b)
 323{
 324    return a.lo == b.lo && a.hi == b.hi;
 325}
 326
 327static inline bool int128_ne(Int128 a, Int128 b)
 328{
 329    return !int128_eq(a, b);
 330}
 331
 332static inline bool int128_ge(Int128 a, Int128 b)
 333{
 334    return a.hi > b.hi || (a.hi == b.hi && a.lo >= b.lo);
 335}
 336
 337static inline bool int128_lt(Int128 a, Int128 b)
 338{
 339    return !int128_ge(a, b);
 340}
 341
 342static inline bool int128_le(Int128 a, Int128 b)
 343{
 344    return int128_ge(b, a);
 345}
 346
 347static inline bool int128_gt(Int128 a, Int128 b)
 348{
 349    return !int128_le(a, b);
 350}
 351
 352static inline bool int128_nz(Int128 a)
 353{
 354    return a.lo || a.hi;
 355}
 356
 357static inline Int128 int128_min(Int128 a, Int128 b)
 358{
 359    return int128_le(a, b) ? a : b;
 360}
 361
 362static inline Int128 int128_max(Int128 a, Int128 b)
 363{
 364    return int128_ge(a, b) ? a : b;
 365}
 366
 367static inline void int128_addto(Int128 *a, Int128 b)
 368{
 369    *a = int128_add(*a, b);
 370}
 371
 372static inline void int128_subfrom(Int128 *a, Int128 b)
 373{
 374    *a = int128_sub(*a, b);
 375}
 376
 377static inline Int128 bswap128(Int128 a)
 378{
 379    return int128_make128(bswap64(a.hi), bswap64(a.lo));
 380}
 381
 382#endif /* CONFIG_INT128 */
 383
 384static inline void bswap128s(Int128 *s)
 385{
 386    *s = bswap128(*s);
 387}
 388
 389#endif /* INT128_H */
 390