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_not(Int128 a)
62{
63 return ~a;
64}
65
66static inline Int128 int128_and(Int128 a, Int128 b)
67{
68 return a & b;
69}
70
71static inline Int128 int128_or(Int128 a, Int128 b)
72{
73 return a | b;
74}
75
76static inline Int128 int128_xor(Int128 a, Int128 b)
77{
78 return a ^ b;
79}
80
81static inline Int128 int128_rshift(Int128 a, int n)
82{
83 return a >> n;
84}
85
86static inline Int128 int128_urshift(Int128 a, int n)
87{
88 return (__uint128_t)a >> n;
89}
90
91static inline Int128 int128_lshift(Int128 a, int n)
92{
93 return a << n;
94}
95
96static inline Int128 int128_add(Int128 a, Int128 b)
97{
98 return a + b;
99}
100
101static inline Int128 int128_neg(Int128 a)
102{
103 return -a;
104}
105
106static inline Int128 int128_sub(Int128 a, Int128 b)
107{
108 return a - b;
109}
110
111static inline bool int128_nonneg(Int128 a)
112{
113 return a >= 0;
114}
115
116static inline bool int128_eq(Int128 a, Int128 b)
117{
118 return a == b;
119}
120
121static inline bool int128_ne(Int128 a, Int128 b)
122{
123 return a != b;
124}
125
126static inline bool int128_ge(Int128 a, Int128 b)
127{
128 return a >= b;
129}
130
131static inline bool int128_uge(Int128 a, Int128 b)
132{
133 return ((__uint128_t)a) >= ((__uint128_t)b);
134}
135
136static inline bool int128_lt(Int128 a, Int128 b)
137{
138 return a < b;
139}
140
141static inline bool int128_ult(Int128 a, Int128 b)
142{
143 return (__uint128_t)a < (__uint128_t)b;
144}
145
146static inline bool int128_le(Int128 a, Int128 b)
147{
148 return a <= b;
149}
150
151static inline bool int128_gt(Int128 a, Int128 b)
152{
153 return a > b;
154}
155
156static inline bool int128_nz(Int128 a)
157{
158 return a != 0;
159}
160
161static inline Int128 int128_min(Int128 a, Int128 b)
162{
163 return a < b ? a : b;
164}
165
166static inline Int128 int128_max(Int128 a, Int128 b)
167{
168 return a > b ? a : b;
169}
170
171static inline void int128_addto(Int128 *a, Int128 b)
172{
173 *a += b;
174}
175
176static inline void int128_subfrom(Int128 *a, Int128 b)
177{
178 *a -= b;
179}
180
181static inline Int128 bswap128(Int128 a)
182{
183#if __has_builtin(__builtin_bswap128)
184 return __builtin_bswap128(a);
185#else
186 return int128_make128(bswap64(int128_gethi(a)), bswap64(int128_getlo(a)));
187#endif
188}
189
190static inline int clz128(Int128 a)
191{
192 if (a >> 64) {
193 return __builtin_clzll(a >> 64);
194 } else {
195 return (a) ? __builtin_clzll((uint64_t)a) + 64 : 128;
196 }
197}
198
199static inline Int128 int128_divu(Int128 a, Int128 b)
200{
201 return (__uint128_t)a / (__uint128_t)b;
202}
203
204static inline Int128 int128_remu(Int128 a, Int128 b)
205{
206 return (__uint128_t)a % (__uint128_t)b;
207}
208
209static inline Int128 int128_divs(Int128 a, Int128 b)
210{
211 return a / b;
212}
213
214static inline Int128 int128_rems(Int128 a, Int128 b)
215{
216 return a % b;
217}
218
219#else
220
221typedef struct Int128 Int128;
222
223
224
225
226
227
228
229
230
231struct Int128 {
232#if HOST_BIG_ENDIAN
233 int64_t hi;
234 uint64_t lo;
235#else
236 uint64_t lo;
237 int64_t hi;
238#endif
239};
240
241static inline Int128 int128_make64(uint64_t a)
242{
243 return (Int128) { .lo = a, .hi = 0 };
244}
245
246static inline Int128 int128_makes64(int64_t a)
247{
248 return (Int128) { .lo = a, .hi = a >> 63 };
249}
250
251static inline Int128 int128_make128(uint64_t lo, uint64_t hi)
252{
253 return (Int128) { .lo = lo, .hi = hi };
254}
255
256static inline uint64_t int128_get64(Int128 a)
257{
258 assert(!a.hi);
259 return a.lo;
260}
261
262static inline uint64_t int128_getlo(Int128 a)
263{
264 return a.lo;
265}
266
267static inline int64_t int128_gethi(Int128 a)
268{
269 return a.hi;
270}
271
272static inline Int128 int128_zero(void)
273{
274 return int128_make64(0);
275}
276
277static inline Int128 int128_one(void)
278{
279 return int128_make64(1);
280}
281
282static inline Int128 int128_2_64(void)
283{
284 return int128_make128(0, 1);
285}
286
287static inline Int128 int128_exts64(int64_t a)
288{
289 return int128_make128(a, (a < 0) ? -1 : 0);
290}
291
292static inline Int128 int128_not(Int128 a)
293{
294 return int128_make128(~a.lo, ~a.hi);
295}
296
297static inline Int128 int128_and(Int128 a, Int128 b)
298{
299 return int128_make128(a.lo & b.lo, a.hi & b.hi);
300}
301
302static inline Int128 int128_or(Int128 a, Int128 b)
303{
304 return int128_make128(a.lo | b.lo, a.hi | b.hi);
305}
306
307static inline Int128 int128_xor(Int128 a, Int128 b)
308{
309 return int128_make128(a.lo ^ b.lo, a.hi ^ b.hi);
310}
311
312static inline Int128 int128_rshift(Int128 a, int n)
313{
314 int64_t h;
315 if (!n) {
316 return a;
317 }
318 h = a.hi >> (n & 63);
319 if (n >= 64) {
320 return int128_make128(h, h >> 63);
321 } else {
322 return int128_make128((a.lo >> n) | ((uint64_t)a.hi << (64 - n)), h);
323 }
324}
325
326static inline Int128 int128_urshift(Int128 a, int n)
327{
328 uint64_t h = a.hi;
329 if (!n) {
330 return a;
331 }
332 h = h >> (n & 63);
333 if (n >= 64) {
334 return int128_make64(h);
335 } else {
336 return int128_make128((a.lo >> n) | ((uint64_t)a.hi << (64 - n)), h);
337 }
338}
339
340static inline Int128 int128_lshift(Int128 a, int n)
341{
342 uint64_t l = a.lo << (n & 63);
343 if (n >= 64) {
344 return int128_make128(0, l);
345 } else if (n > 0) {
346 return int128_make128(l, (a.hi << n) | (a.lo >> (64 - n)));
347 }
348 return a;
349}
350
351static inline Int128 int128_add(Int128 a, Int128 b)
352{
353 uint64_t lo = a.lo + b.lo;
354
355
356
357
358
359
360
361 return int128_make128(lo, (uint64_t)a.hi + b.hi + (lo < a.lo));
362}
363
364static inline Int128 int128_neg(Int128 a)
365{
366 uint64_t lo = -a.lo;
367 return int128_make128(lo, ~(uint64_t)a.hi + !lo);
368}
369
370static inline Int128 int128_sub(Int128 a, Int128 b)
371{
372 return int128_make128(a.lo - b.lo, (uint64_t)a.hi - b.hi - (a.lo < b.lo));
373}
374
375static inline bool int128_nonneg(Int128 a)
376{
377 return a.hi >= 0;
378}
379
380static inline bool int128_eq(Int128 a, Int128 b)
381{
382 return a.lo == b.lo && a.hi == b.hi;
383}
384
385static inline bool int128_ne(Int128 a, Int128 b)
386{
387 return !int128_eq(a, b);
388}
389
390static inline bool int128_ge(Int128 a, Int128 b)
391{
392 return a.hi > b.hi || (a.hi == b.hi && a.lo >= b.lo);
393}
394
395static inline bool int128_uge(Int128 a, Int128 b)
396{
397 return (uint64_t)a.hi > (uint64_t)b.hi || (a.hi == b.hi && a.lo >= b.lo);
398}
399
400static inline bool int128_lt(Int128 a, Int128 b)
401{
402 return !int128_ge(a, b);
403}
404
405static inline bool int128_ult(Int128 a, Int128 b)
406{
407 return !int128_uge(a, b);
408}
409
410static inline bool int128_le(Int128 a, Int128 b)
411{
412 return int128_ge(b, a);
413}
414
415static inline bool int128_gt(Int128 a, Int128 b)
416{
417 return !int128_le(a, b);
418}
419
420static inline bool int128_nz(Int128 a)
421{
422 return a.lo || a.hi;
423}
424
425static inline Int128 int128_min(Int128 a, Int128 b)
426{
427 return int128_le(a, b) ? a : b;
428}
429
430static inline Int128 int128_max(Int128 a, Int128 b)
431{
432 return int128_ge(a, b) ? a : b;
433}
434
435static inline void int128_addto(Int128 *a, Int128 b)
436{
437 *a = int128_add(*a, b);
438}
439
440static inline void int128_subfrom(Int128 *a, Int128 b)
441{
442 *a = int128_sub(*a, b);
443}
444
445static inline Int128 bswap128(Int128 a)
446{
447 return int128_make128(bswap64(a.hi), bswap64(a.lo));
448}
449
450static inline int clz128(Int128 a)
451{
452 if (a.hi) {
453 return __builtin_clzll(a.hi);
454 } else {
455 return (a.lo) ? __builtin_clzll(a.lo) + 64 : 128;
456 }
457}
458
459Int128 int128_divu(Int128, Int128);
460Int128 int128_remu(Int128, Int128);
461Int128 int128_divs(Int128, Int128);
462Int128 int128_rems(Int128, Int128);
463
464#endif
465
466static inline void bswap128s(Int128 *s)
467{
468 *s = bswap128(*s);
469}
470
471#define UINT128_MAX int128_make128(~0LL, ~0LL)
472#define INT128_MAX int128_make128(UINT64_MAX, INT64_MAX)
473#define INT128_MIN int128_make128(0, INT64_MIN)
474
475#endif
476