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_add(Int128 a, Int128 b)
67{
68 return a + b;
69}
70
71static inline Int128 int128_neg(Int128 a)
72{
73 return -a;
74}
75
76static inline Int128 int128_sub(Int128 a, Int128 b)
77{
78 return a - b;
79}
80
81static inline bool int128_nonneg(Int128 a)
82{
83 return a >= 0;
84}
85
86static inline bool int128_eq(Int128 a, Int128 b)
87{
88 return a == b;
89}
90
91static inline bool int128_ne(Int128 a, Int128 b)
92{
93 return a != b;
94}
95
96static inline bool int128_ge(Int128 a, Int128 b)
97{
98 return a >= b;
99}
100
101static inline bool int128_lt(Int128 a, Int128 b)
102{
103 return a < b;
104}
105
106static inline bool int128_le(Int128 a, Int128 b)
107{
108 return a <= b;
109}
110
111static inline bool int128_gt(Int128 a, Int128 b)
112{
113 return a > b;
114}
115
116static inline bool int128_nz(Int128 a)
117{
118 return a != 0;
119}
120
121static inline Int128 int128_min(Int128 a, Int128 b)
122{
123 return a < b ? a : b;
124}
125
126static inline Int128 int128_max(Int128 a, Int128 b)
127{
128 return a > b ? a : b;
129}
130
131static inline void int128_addto(Int128 *a, Int128 b)
132{
133 *a += b;
134}
135
136static inline void int128_subfrom(Int128 *a, Int128 b)
137{
138 *a -= b;
139}
140
141static inline Int128 bswap128(Int128 a)
142{
143 return int128_make128(bswap64(int128_gethi(a)), bswap64(int128_getlo(a)));
144}
145
146#else /* !CONFIG_INT128 */
147
148typedef struct Int128 Int128;
149
150struct Int128 {
151 uint64_t lo;
152 int64_t hi;
153};
154
155static inline Int128 int128_make64(uint64_t a)
156{
157 return (Int128) { a, 0 };
158}
159
160static inline Int128 int128_make128(uint64_t lo, uint64_t hi)
161{
162 return (Int128) { lo, hi };
163}
164
165static inline uint64_t int128_get64(Int128 a)
166{
167 assert(!a.hi);
168 return a.lo;
169}
170
171static inline uint64_t int128_getlo(Int128 a)
172{
173 return a.lo;
174}
175
176static inline int64_t int128_gethi(Int128 a)
177{
178 return a.hi;
179}
180
181static inline Int128 int128_zero(void)
182{
183 return int128_make64(0);
184}
185
186static inline Int128 int128_one(void)
187{
188 return int128_make64(1);
189}
190
191static inline Int128 int128_2_64(void)
192{
193 return (Int128) { 0, 1 };
194}
195
196static inline Int128 int128_exts64(int64_t a)
197{
198 return (Int128) { .lo = a, .hi = (a < 0) ? -1 : 0 };
199}
200
201static inline Int128 int128_and(Int128 a, Int128 b)
202{
203 return (Int128) { a.lo & b.lo, a.hi & b.hi };
204}
205
206static inline Int128 int128_rshift(Int128 a, int n)
207{
208 int64_t h;
209 if (!n) {
210 return a;
211 }
212 h = a.hi >> (n & 63);
213 if (n >= 64) {
214 return int128_make128(h, h >> 63);
215 } else {
216 return int128_make128((a.lo >> n) | ((uint64_t)a.hi << (64 - n)), h);
217 }
218}
219
220static inline Int128 int128_add(Int128 a, Int128 b)
221{
222 uint64_t lo = a.lo + b.lo;
223
224 /* a.lo <= a.lo + b.lo < a.lo + k (k is the base, 2^64). Hence,
225 * a.lo + b.lo >= k implies 0 <= lo = a.lo + b.lo - k < a.lo.
226 * Similarly, a.lo + b.lo < k implies a.lo <= lo = a.lo + b.lo < k.
227 *
228 * So the carry is lo < a.lo.
229 */
230 return int128_make128(lo, (uint64_t)a.hi + b.hi + (lo < a.lo));
231}
232
233static inline Int128 int128_neg(Int128 a)
234{
235 uint64_t lo = -a.lo;
236 return int128_make128(lo, ~(uint64_t)a.hi + !lo);
237}
238
239static inline Int128 int128_sub(Int128 a, Int128 b)
240{
241 return int128_make128(a.lo - b.lo, (uint64_t)a.hi - b.hi - (a.lo < b.lo));
242}
243
244static inline bool int128_nonneg(Int128 a)
245{
246 return a.hi >= 0;
247}
248
249static inline bool int128_eq(Int128 a, Int128 b)
250{
251 return a.lo == b.lo && a.hi == b.hi;
252}
253
254static inline bool int128_ne(Int128 a, Int128 b)
255{
256 return !int128_eq(a, b);
257}
258
259static inline bool int128_ge(Int128 a, Int128 b)
260{
261 return a.hi > b.hi || (a.hi == b.hi && a.lo >= b.lo);
262}
263
264static inline bool int128_lt(Int128 a, Int128 b)
265{
266 return !int128_ge(a, b);
267}
268
269static inline bool int128_le(Int128 a, Int128 b)
270{
271 return int128_ge(b, a);
272}
273
274static inline bool int128_gt(Int128 a, Int128 b)
275{
276 return !int128_le(a, b);
277}
278
279static inline bool int128_nz(Int128 a)
280{
281 return a.lo || a.hi;
282}
283
284static inline Int128 int128_min(Int128 a, Int128 b)
285{
286 return int128_le(a, b) ? a : b;
287}
288
289static inline Int128 int128_max(Int128 a, Int128 b)
290{
291 return int128_ge(a, b) ? a : b;
292}
293
294static inline void int128_addto(Int128 *a, Int128 b)
295{
296 *a = int128_add(*a, b);
297}
298
299static inline void int128_subfrom(Int128 *a, Int128 b)
300{
301 *a = int128_sub(*a, b);
302}
303
304#endif /* CONFIG_INT128 */
305#endif /* INT128_H */
306