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_lshift(Int128 a, int n)
  67{
  68    return a << n;
  69}
  70
  71static inline Int128 int128_add(Int128 a, Int128 b)
  72{
  73    return a + b;
  74}
  75
  76static inline Int128 int128_neg(Int128 a)
  77{
  78    return -a;
  79}
  80
  81static inline Int128 int128_sub(Int128 a, Int128 b)
  82{
  83    return a - b;
  84}
  85
  86static inline Int128 int128_mul(Int128 a, Int128 b)
  87{
  88    return a * b;
  89}
  90
  91static inline Int128 int128_div(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
 163/* FIXME: Update the file with support for
 164 *     int128_mul(),
 165 *     int128_div(),
 166 *     int128_lshift()
 167 */
 168_Static_assert(0, "arm generic timer needs __Int128 defined");
 169
 170typedef struct Int128 Int128;
 171
 172struct Int128 {
 173    uint64_t lo;
 174    int64_t hi;
 175};
 176
 177static inline Int128 int128_make64(uint64_t a)
 178{
 179    return (Int128) { a, 0 };
 180}
 181
 182static inline Int128 int128_make128(uint64_t lo, uint64_t hi)
 183{
 184    return (Int128) { lo, hi };
 185}
 186
 187static inline uint64_t int128_get64(Int128 a)
 188{
 189    assert(!a.hi);
 190    return a.lo;
 191}
 192
 193static inline uint64_t int128_getlo(Int128 a)
 194{
 195    return a.lo;
 196}
 197
 198static inline int64_t int128_gethi(Int128 a)
 199{
 200    return a.hi;
 201}
 202
 203static inline Int128 int128_zero(void)
 204{
 205    return int128_make64(0);
 206}
 207
 208static inline Int128 int128_one(void)
 209{
 210    return int128_make64(1);
 211}
 212
 213static inline Int128 int128_2_64(void)
 214{
 215    return (Int128) { 0, 1 };
 216}
 217
 218static inline Int128 int128_exts64(int64_t a)
 219{
 220    return (Int128) { .lo = a, .hi = (a < 0) ? -1 : 0 };
 221}
 222
 223static inline Int128 int128_and(Int128 a, Int128 b)
 224{
 225    return (Int128) { a.lo & b.lo, a.hi & b.hi };
 226}
 227
 228static inline Int128 int128_rshift(Int128 a, int n)
 229{
 230    int64_t h;
 231    if (!n) {
 232        return a;
 233    }
 234    h = a.hi >> (n & 63);
 235    if (n >= 64) {
 236        return int128_make128(h, h >> 63);
 237    } else {
 238        return int128_make128((a.lo >> n) | ((uint64_t)a.hi << (64 - n)), h);
 239    }
 240}
 241
 242static inline Int128 int128_add(Int128 a, Int128 b)
 243{
 244    uint64_t lo = a.lo + b.lo;
 245
 246    /* a.lo <= a.lo + b.lo < a.lo + k (k is the base, 2^64).  Hence,
 247     * a.lo + b.lo >= k implies 0 <= lo = a.lo + b.lo - k < a.lo.
 248     * Similarly, a.lo + b.lo < k implies a.lo <= lo = a.lo + b.lo < k.
 249     *
 250     * So the carry is lo < a.lo.
 251     */
 252    return int128_make128(lo, (uint64_t)a.hi + b.hi + (lo < a.lo));
 253}
 254
 255static inline Int128 int128_neg(Int128 a)
 256{
 257    uint64_t lo = -a.lo;
 258    return int128_make128(lo, ~(uint64_t)a.hi + !lo);
 259}
 260
 261static inline Int128 int128_sub(Int128 a, Int128 b)
 262{
 263    return int128_make128(a.lo - b.lo, (uint64_t)a.hi - b.hi - (a.lo < b.lo));
 264}
 265
 266static inline bool int128_nonneg(Int128 a)
 267{
 268    return a.hi >= 0;
 269}
 270
 271static inline bool int128_eq(Int128 a, Int128 b)
 272{
 273    return a.lo == b.lo && a.hi == b.hi;
 274}
 275
 276static inline bool int128_ne(Int128 a, Int128 b)
 277{
 278    return !int128_eq(a, b);
 279}
 280
 281static inline bool int128_ge(Int128 a, Int128 b)
 282{
 283    return a.hi > b.hi || (a.hi == b.hi && a.lo >= b.lo);
 284}
 285
 286static inline bool int128_lt(Int128 a, Int128 b)
 287{
 288    return !int128_ge(a, b);
 289}
 290
 291static inline bool int128_le(Int128 a, Int128 b)
 292{
 293    return int128_ge(b, a);
 294}
 295
 296static inline bool int128_gt(Int128 a, Int128 b)
 297{
 298    return !int128_le(a, b);
 299}
 300
 301static inline bool int128_nz(Int128 a)
 302{
 303    return a.lo || a.hi;
 304}
 305
 306static inline Int128 int128_min(Int128 a, Int128 b)
 307{
 308    return int128_le(a, b) ? a : b;
 309}
 310
 311static inline Int128 int128_max(Int128 a, Int128 b)
 312{
 313    return int128_ge(a, b) ? a : b;
 314}
 315
 316static inline void int128_addto(Int128 *a, Int128 b)
 317{
 318    *a = int128_add(*a, b);
 319}
 320
 321static inline void int128_subfrom(Int128 *a, Int128 b)
 322{
 323    *a = int128_sub(*a, b);
 324}
 325
 326#endif /* CONFIG_INT128 */
 327#endif /* INT128_H */
 328