Statistics
| Branch: | Revision:

root / include / qemu / int128.h @ 052e87b0

History | View | Annotate | Download (2.3 kB)

1
#ifndef INT128_H
2
#define INT128_H
3

    
4
typedef struct Int128 Int128;
5

    
6
struct Int128 {
7
    uint64_t lo;
8
    int64_t hi;
9
};
10

    
11
static inline Int128 int128_make64(uint64_t a)
12
{
13
    return (Int128) { a, 0 };
14
}
15

    
16
static inline uint64_t int128_get64(Int128 a)
17
{
18
    assert(!a.hi);
19
    return a.lo;
20
}
21

    
22
static inline Int128 int128_zero(void)
23
{
24
    return int128_make64(0);
25
}
26

    
27
static inline Int128 int128_one(void)
28
{
29
    return int128_make64(1);
30
}
31

    
32
static inline Int128 int128_2_64(void)
33
{
34
    return (Int128) { 0, 1 };
35
}
36

    
37
static inline Int128 int128_and(Int128 a, Int128 b)
38
{
39
    return (Int128) { a.lo & b.lo, a.hi & b.hi };
40
}
41

    
42
static inline Int128 int128_rshift(Int128 a, int n)
43
{
44
    int64_t h;
45
    if (!n) {
46
        return a;
47
    }
48
    h = a.hi >> (n & 63);
49
    if (n >= 64) {
50
        return (Int128) { h, h >> 63 };
51
    } else {
52
        return (Int128) { (a.lo >> n) | (a.hi << (64 - n)), h };
53
    }
54
}
55

    
56
static inline Int128 int128_add(Int128 a, Int128 b)
57
{
58
    Int128 r = { a.lo + b.lo, a.hi + b.hi };
59
    r.hi += (r.lo < a.lo) || (r.lo < b.lo);
60
    return r;
61
}
62

    
63
static inline Int128 int128_neg(Int128 a)
64
{
65
    a.lo = ~a.lo;
66
    a.hi = ~a.hi;
67
    return int128_add(a, int128_one());
68
}
69

    
70
static inline Int128 int128_sub(Int128 a, Int128 b)
71
{
72
    return int128_add(a, int128_neg(b));
73
}
74

    
75
static inline bool int128_nonneg(Int128 a)
76
{
77
    return a.hi >= 0;
78
}
79

    
80
static inline bool int128_eq(Int128 a, Int128 b)
81
{
82
    return a.lo == b.lo && a.hi == b.hi;
83
}
84

    
85
static inline bool int128_ne(Int128 a, Int128 b)
86
{
87
    return !int128_eq(a, b);
88
}
89

    
90
static inline bool int128_ge(Int128 a, Int128 b)
91
{
92
    return int128_nonneg(int128_sub(a, b));
93
}
94

    
95
static inline bool int128_lt(Int128 a, Int128 b)
96
{
97
    return !int128_ge(a, b);
98
}
99

    
100
static inline bool int128_le(Int128 a, Int128 b)
101
{
102
    return int128_ge(b, a);
103
}
104

    
105
static inline bool int128_gt(Int128 a, Int128 b)
106
{
107
    return !int128_le(a, b);
108
}
109

    
110
static inline bool int128_nz(Int128 a)
111
{
112
    return a.lo || a.hi;
113
}
114

    
115
static inline Int128 int128_min(Int128 a, Int128 b)
116
{
117
    return int128_le(a, b) ? a : b;
118
}
119

    
120
static inline Int128 int128_max(Int128 a, Int128 b)
121
{
122
    return int128_ge(a, b) ? a : b;
123
}
124

    
125
static inline void int128_addto(Int128 *a, Int128 b)
126
{
127
    *a = int128_add(*a, b);
128
}
129

    
130
static inline void int128_subfrom(Int128 *a, Int128 b)
131
{
132
    *a = int128_sub(*a, b);
133
}
134

    
135
#endif