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