cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

int128.h (6543B)


      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_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#if __has_builtin(__builtin_bswap128)
    159    return __builtin_bswap128(a);
    160#else
    161    return int128_make128(bswap64(int128_gethi(a)), bswap64(int128_getlo(a)));
    162#endif
    163}
    164
    165#else /* !CONFIG_INT128 */
    166
    167typedef struct Int128 Int128;
    168
    169/*
    170 * We guarantee that the in-memory byte representation of an
    171 * Int128 is that of a host-endian-order 128-bit integer
    172 * (whether using this struct or the __int128_t version of the type).
    173 * Some code using this type relies on this (eg when copying it into
    174 * guest memory or a gdb protocol buffer, or by using Int128 in
    175 * a union with other integer types).
    176 */
    177struct Int128 {
    178#ifdef HOST_WORDS_BIGENDIAN
    179    int64_t hi;
    180    uint64_t lo;
    181#else
    182    uint64_t lo;
    183    int64_t hi;
    184#endif
    185};
    186
    187static inline Int128 int128_make64(uint64_t a)
    188{
    189    return (Int128) { .lo = a, .hi = 0 };
    190}
    191
    192static inline Int128 int128_makes64(int64_t a)
    193{
    194    return (Int128) { .lo = a, .hi = a >> 63 };
    195}
    196
    197static inline Int128 int128_make128(uint64_t lo, uint64_t hi)
    198{
    199    return (Int128) { .lo = lo, .hi = hi };
    200}
    201
    202static inline uint64_t int128_get64(Int128 a)
    203{
    204    assert(!a.hi);
    205    return a.lo;
    206}
    207
    208static inline uint64_t int128_getlo(Int128 a)
    209{
    210    return a.lo;
    211}
    212
    213static inline int64_t int128_gethi(Int128 a)
    214{
    215    return a.hi;
    216}
    217
    218static inline Int128 int128_zero(void)
    219{
    220    return int128_make64(0);
    221}
    222
    223static inline Int128 int128_one(void)
    224{
    225    return int128_make64(1);
    226}
    227
    228static inline Int128 int128_2_64(void)
    229{
    230    return int128_make128(0, 1);
    231}
    232
    233static inline Int128 int128_exts64(int64_t a)
    234{
    235    return int128_make128(a, (a < 0) ? -1 : 0);
    236}
    237
    238static inline Int128 int128_and(Int128 a, Int128 b)
    239{
    240    return int128_make128(a.lo & b.lo, a.hi & b.hi);
    241}
    242
    243static inline Int128 int128_or(Int128 a, Int128 b)
    244{
    245    return int128_make128(a.lo | b.lo, a.hi | b.hi);
    246}
    247
    248static inline Int128 int128_rshift(Int128 a, int n)
    249{
    250    int64_t h;
    251    if (!n) {
    252        return a;
    253    }
    254    h = a.hi >> (n & 63);
    255    if (n >= 64) {
    256        return int128_make128(h, h >> 63);
    257    } else {
    258        return int128_make128((a.lo >> n) | ((uint64_t)a.hi << (64 - n)), h);
    259    }
    260}
    261
    262static inline Int128 int128_lshift(Int128 a, int n)
    263{
    264    uint64_t l = a.lo << (n & 63);
    265    if (n >= 64) {
    266        return int128_make128(0, l);
    267    } else if (n > 0) {
    268        return int128_make128(l, (a.hi << n) | (a.lo >> (64 - n)));
    269    }
    270    return a;
    271}
    272
    273static inline Int128 int128_add(Int128 a, Int128 b)
    274{
    275    uint64_t lo = a.lo + b.lo;
    276
    277    /* a.lo <= a.lo + b.lo < a.lo + k (k is the base, 2^64).  Hence,
    278     * a.lo + b.lo >= k implies 0 <= lo = a.lo + b.lo - k < a.lo.
    279     * Similarly, a.lo + b.lo < k implies a.lo <= lo = a.lo + b.lo < k.
    280     *
    281     * So the carry is lo < a.lo.
    282     */
    283    return int128_make128(lo, (uint64_t)a.hi + b.hi + (lo < a.lo));
    284}
    285
    286static inline Int128 int128_neg(Int128 a)
    287{
    288    uint64_t lo = -a.lo;
    289    return int128_make128(lo, ~(uint64_t)a.hi + !lo);
    290}
    291
    292static inline Int128 int128_sub(Int128 a, Int128 b)
    293{
    294    return int128_make128(a.lo - b.lo, (uint64_t)a.hi - b.hi - (a.lo < b.lo));
    295}
    296
    297static inline bool int128_nonneg(Int128 a)
    298{
    299    return a.hi >= 0;
    300}
    301
    302static inline bool int128_eq(Int128 a, Int128 b)
    303{
    304    return a.lo == b.lo && a.hi == b.hi;
    305}
    306
    307static inline bool int128_ne(Int128 a, Int128 b)
    308{
    309    return !int128_eq(a, b);
    310}
    311
    312static inline bool int128_ge(Int128 a, Int128 b)
    313{
    314    return a.hi > b.hi || (a.hi == b.hi && a.lo >= b.lo);
    315}
    316
    317static inline bool int128_lt(Int128 a, Int128 b)
    318{
    319    return !int128_ge(a, b);
    320}
    321
    322static inline bool int128_le(Int128 a, Int128 b)
    323{
    324    return int128_ge(b, a);
    325}
    326
    327static inline bool int128_gt(Int128 a, Int128 b)
    328{
    329    return !int128_le(a, b);
    330}
    331
    332static inline bool int128_nz(Int128 a)
    333{
    334    return a.lo || a.hi;
    335}
    336
    337static inline Int128 int128_min(Int128 a, Int128 b)
    338{
    339    return int128_le(a, b) ? a : b;
    340}
    341
    342static inline Int128 int128_max(Int128 a, Int128 b)
    343{
    344    return int128_ge(a, b) ? a : b;
    345}
    346
    347static inline void int128_addto(Int128 *a, Int128 b)
    348{
    349    *a = int128_add(*a, b);
    350}
    351
    352static inline void int128_subfrom(Int128 *a, Int128 b)
    353{
    354    *a = int128_sub(*a, b);
    355}
    356
    357static inline Int128 bswap128(Int128 a)
    358{
    359    return int128_make128(bswap64(a.hi), bswap64(a.lo));
    360}
    361
    362#endif /* CONFIG_INT128 */
    363
    364static inline void bswap128s(Int128 *s)
    365{
    366    *s = bswap128(*s);
    367}
    368
    369#endif /* INT128_H */