xref: /qemu/include/qemu/int128.h (revision b7cd3db6f4d79f11abf0572fdc5e41d0811ea2e2)
1*b7cd3db6SAvi Kivity #ifndef INT128_H
2*b7cd3db6SAvi Kivity #define INT128_H
3*b7cd3db6SAvi Kivity 
4*b7cd3db6SAvi Kivity typedef struct Int128 Int128;
5*b7cd3db6SAvi Kivity 
6*b7cd3db6SAvi Kivity struct Int128 {
7*b7cd3db6SAvi Kivity     uint64_t lo;
8*b7cd3db6SAvi Kivity     int64_t hi;
9*b7cd3db6SAvi Kivity };
10*b7cd3db6SAvi Kivity 
11*b7cd3db6SAvi Kivity static inline Int128 int128_make64(uint64_t a)
12*b7cd3db6SAvi Kivity {
13*b7cd3db6SAvi Kivity     return (Int128) { a, 0 };
14*b7cd3db6SAvi Kivity }
15*b7cd3db6SAvi Kivity 
16*b7cd3db6SAvi Kivity static inline uint64_t int128_get64(Int128 a)
17*b7cd3db6SAvi Kivity {
18*b7cd3db6SAvi Kivity     assert(!a.hi);
19*b7cd3db6SAvi Kivity     return a.lo;
20*b7cd3db6SAvi Kivity }
21*b7cd3db6SAvi Kivity 
22*b7cd3db6SAvi Kivity static inline Int128 int128_zero(void)
23*b7cd3db6SAvi Kivity {
24*b7cd3db6SAvi Kivity     return int128_make64(0);
25*b7cd3db6SAvi Kivity }
26*b7cd3db6SAvi Kivity 
27*b7cd3db6SAvi Kivity static inline Int128 int128_one(void)
28*b7cd3db6SAvi Kivity {
29*b7cd3db6SAvi Kivity     return int128_make64(1);
30*b7cd3db6SAvi Kivity }
31*b7cd3db6SAvi Kivity 
32*b7cd3db6SAvi Kivity static inline Int128 int128_2_64(void)
33*b7cd3db6SAvi Kivity {
34*b7cd3db6SAvi Kivity     return (Int128) { 0, 1 };
35*b7cd3db6SAvi Kivity }
36*b7cd3db6SAvi Kivity 
37*b7cd3db6SAvi Kivity static inline Int128 int128_add(Int128 a, Int128 b)
38*b7cd3db6SAvi Kivity {
39*b7cd3db6SAvi Kivity     Int128 r = { a.lo + b.lo, a.hi + b.hi };
40*b7cd3db6SAvi Kivity     r.hi += (r.lo < a.lo) || (r.lo < b.lo);
41*b7cd3db6SAvi Kivity     return r;
42*b7cd3db6SAvi Kivity }
43*b7cd3db6SAvi Kivity 
44*b7cd3db6SAvi Kivity static inline Int128 int128_neg(Int128 a)
45*b7cd3db6SAvi Kivity {
46*b7cd3db6SAvi Kivity     a.lo = ~a.lo;
47*b7cd3db6SAvi Kivity     a.hi = ~a.hi;
48*b7cd3db6SAvi Kivity     return int128_add(a, int128_one());
49*b7cd3db6SAvi Kivity }
50*b7cd3db6SAvi Kivity 
51*b7cd3db6SAvi Kivity static inline Int128 int128_sub(Int128 a, Int128 b)
52*b7cd3db6SAvi Kivity {
53*b7cd3db6SAvi Kivity     return int128_add(a, int128_neg(b));
54*b7cd3db6SAvi Kivity }
55*b7cd3db6SAvi Kivity 
56*b7cd3db6SAvi Kivity static inline bool int128_nonneg(Int128 a)
57*b7cd3db6SAvi Kivity {
58*b7cd3db6SAvi Kivity     return a.hi >= 0;
59*b7cd3db6SAvi Kivity }
60*b7cd3db6SAvi Kivity 
61*b7cd3db6SAvi Kivity static inline bool int128_eq(Int128 a, Int128 b)
62*b7cd3db6SAvi Kivity {
63*b7cd3db6SAvi Kivity     return a.lo == b.lo && a.hi == b.hi;
64*b7cd3db6SAvi Kivity }
65*b7cd3db6SAvi Kivity 
66*b7cd3db6SAvi Kivity static inline bool int128_ne(Int128 a, Int128 b)
67*b7cd3db6SAvi Kivity {
68*b7cd3db6SAvi Kivity     return !int128_eq(a, b);
69*b7cd3db6SAvi Kivity }
70*b7cd3db6SAvi Kivity 
71*b7cd3db6SAvi Kivity static inline bool int128_ge(Int128 a, Int128 b)
72*b7cd3db6SAvi Kivity {
73*b7cd3db6SAvi Kivity     return int128_nonneg(int128_sub(a, b));
74*b7cd3db6SAvi Kivity }
75*b7cd3db6SAvi Kivity 
76*b7cd3db6SAvi Kivity static inline bool int128_lt(Int128 a, Int128 b)
77*b7cd3db6SAvi Kivity {
78*b7cd3db6SAvi Kivity     return !int128_ge(a, b);
79*b7cd3db6SAvi Kivity }
80*b7cd3db6SAvi Kivity 
81*b7cd3db6SAvi Kivity static inline bool int128_le(Int128 a, Int128 b)
82*b7cd3db6SAvi Kivity {
83*b7cd3db6SAvi Kivity     return int128_ge(b, a);
84*b7cd3db6SAvi Kivity }
85*b7cd3db6SAvi Kivity 
86*b7cd3db6SAvi Kivity static inline bool int128_gt(Int128 a, Int128 b)
87*b7cd3db6SAvi Kivity {
88*b7cd3db6SAvi Kivity     return !int128_le(a, b);
89*b7cd3db6SAvi Kivity }
90*b7cd3db6SAvi Kivity 
91*b7cd3db6SAvi Kivity static inline bool int128_nz(Int128 a)
92*b7cd3db6SAvi Kivity {
93*b7cd3db6SAvi Kivity     return a.lo || a.hi;
94*b7cd3db6SAvi Kivity }
95*b7cd3db6SAvi Kivity 
96*b7cd3db6SAvi Kivity static inline Int128 int128_min(Int128 a, Int128 b)
97*b7cd3db6SAvi Kivity {
98*b7cd3db6SAvi Kivity     return int128_le(a, b) ? a : b;
99*b7cd3db6SAvi Kivity }
100*b7cd3db6SAvi Kivity 
101*b7cd3db6SAvi Kivity static inline Int128 int128_max(Int128 a, Int128 b)
102*b7cd3db6SAvi Kivity {
103*b7cd3db6SAvi Kivity     return int128_ge(a, b) ? a : b;
104*b7cd3db6SAvi Kivity }
105*b7cd3db6SAvi Kivity 
106*b7cd3db6SAvi Kivity static inline void int128_addto(Int128 *a, Int128 b)
107*b7cd3db6SAvi Kivity {
108*b7cd3db6SAvi Kivity     *a = int128_add(*a, b);
109*b7cd3db6SAvi Kivity }
110*b7cd3db6SAvi Kivity 
111*b7cd3db6SAvi Kivity static inline void int128_subfrom(Int128 *a, Int128 b)
112*b7cd3db6SAvi Kivity {
113*b7cd3db6SAvi Kivity     *a = int128_sub(*a, b);
114*b7cd3db6SAvi Kivity }
115*b7cd3db6SAvi Kivity 
116*b7cd3db6SAvi Kivity #endif
117