xref: /qemu/include/qemu/int128.h (revision 1fe8ac35)
1 #ifndef INT128_H
2 #define INT128_H
3 
4 #include "qemu/bswap.h"
5 
6 #ifdef CONFIG_INT128
7 typedef __int128_t Int128;
8 
9 static inline Int128 int128_make64(uint64_t a)
10 {
11     return a;
12 }
13 
14 static inline Int128 int128_makes64(int64_t a)
15 {
16     return a;
17 }
18 
19 static inline Int128 int128_make128(uint64_t lo, uint64_t hi)
20 {
21     return (__uint128_t)hi << 64 | lo;
22 }
23 
24 static inline uint64_t int128_get64(Int128 a)
25 {
26     uint64_t r = a;
27     assert(r == a);
28     return r;
29 }
30 
31 static inline uint64_t int128_getlo(Int128 a)
32 {
33     return a;
34 }
35 
36 static inline int64_t int128_gethi(Int128 a)
37 {
38     return a >> 64;
39 }
40 
41 static inline Int128 int128_zero(void)
42 {
43     return 0;
44 }
45 
46 static inline Int128 int128_one(void)
47 {
48     return 1;
49 }
50 
51 static inline Int128 int128_2_64(void)
52 {
53     return (Int128)1 << 64;
54 }
55 
56 static inline Int128 int128_exts64(int64_t a)
57 {
58     return a;
59 }
60 
61 static inline Int128 int128_not(Int128 a)
62 {
63     return ~a;
64 }
65 
66 static inline Int128 int128_and(Int128 a, Int128 b)
67 {
68     return a & b;
69 }
70 
71 static inline Int128 int128_or(Int128 a, Int128 b)
72 {
73     return a | b;
74 }
75 
76 static inline Int128 int128_xor(Int128 a, Int128 b)
77 {
78     return a ^ b;
79 }
80 
81 static inline Int128 int128_rshift(Int128 a, int n)
82 {
83     return a >> n;
84 }
85 
86 static inline Int128 int128_urshift(Int128 a, int n)
87 {
88     return (__uint128_t)a >> n;
89 }
90 
91 static inline Int128 int128_lshift(Int128 a, int n)
92 {
93     return a << n;
94 }
95 
96 static inline Int128 int128_add(Int128 a, Int128 b)
97 {
98     return a + b;
99 }
100 
101 static inline Int128 int128_neg(Int128 a)
102 {
103     return -a;
104 }
105 
106 static inline Int128 int128_sub(Int128 a, Int128 b)
107 {
108     return a - b;
109 }
110 
111 static inline bool int128_nonneg(Int128 a)
112 {
113     return a >= 0;
114 }
115 
116 static inline bool int128_eq(Int128 a, Int128 b)
117 {
118     return a == b;
119 }
120 
121 static inline bool int128_ne(Int128 a, Int128 b)
122 {
123     return a != b;
124 }
125 
126 static inline bool int128_ge(Int128 a, Int128 b)
127 {
128     return a >= b;
129 }
130 
131 static inline bool int128_uge(Int128 a, Int128 b)
132 {
133     return ((__uint128_t)a) >= ((__uint128_t)b);
134 }
135 
136 static inline bool int128_lt(Int128 a, Int128 b)
137 {
138     return a < b;
139 }
140 
141 static inline bool int128_ult(Int128 a, Int128 b)
142 {
143     return (__uint128_t)a < (__uint128_t)b;
144 }
145 
146 static inline bool int128_le(Int128 a, Int128 b)
147 {
148     return a <= b;
149 }
150 
151 static inline bool int128_gt(Int128 a, Int128 b)
152 {
153     return a > b;
154 }
155 
156 static inline bool int128_nz(Int128 a)
157 {
158     return a != 0;
159 }
160 
161 static inline Int128 int128_min(Int128 a, Int128 b)
162 {
163     return a < b ? a : b;
164 }
165 
166 static inline Int128 int128_max(Int128 a, Int128 b)
167 {
168     return a > b ? a : b;
169 }
170 
171 static inline void int128_addto(Int128 *a, Int128 b)
172 {
173     *a += b;
174 }
175 
176 static inline void int128_subfrom(Int128 *a, Int128 b)
177 {
178     *a -= b;
179 }
180 
181 static 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 
190 static 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 
199 static inline Int128 int128_divu(Int128 a, Int128 b)
200 {
201     return (__uint128_t)a / (__uint128_t)b;
202 }
203 
204 static inline Int128 int128_remu(Int128 a, Int128 b)
205 {
206     return (__uint128_t)a % (__uint128_t)b;
207 }
208 
209 static inline Int128 int128_divs(Int128 a, Int128 b)
210 {
211     return a / b;
212 }
213 
214 static inline Int128 int128_rems(Int128 a, Int128 b)
215 {
216     return a % b;
217 }
218 
219 #else /* !CONFIG_INT128 */
220 
221 typedef struct Int128 Int128;
222 
223 /*
224  * We guarantee that the in-memory byte representation of an
225  * Int128 is that of a host-endian-order 128-bit integer
226  * (whether using this struct or the __int128_t version of the type).
227  * Some code using this type relies on this (eg when copying it into
228  * guest memory or a gdb protocol buffer, or by using Int128 in
229  * a union with other integer types).
230  */
231 struct 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 
241 static inline Int128 int128_make64(uint64_t a)
242 {
243     return (Int128) { .lo = a, .hi = 0 };
244 }
245 
246 static inline Int128 int128_makes64(int64_t a)
247 {
248     return (Int128) { .lo = a, .hi = a >> 63 };
249 }
250 
251 static inline Int128 int128_make128(uint64_t lo, uint64_t hi)
252 {
253     return (Int128) { .lo = lo, .hi = hi };
254 }
255 
256 static inline uint64_t int128_get64(Int128 a)
257 {
258     assert(!a.hi);
259     return a.lo;
260 }
261 
262 static inline uint64_t int128_getlo(Int128 a)
263 {
264     return a.lo;
265 }
266 
267 static inline int64_t int128_gethi(Int128 a)
268 {
269     return a.hi;
270 }
271 
272 static inline Int128 int128_zero(void)
273 {
274     return int128_make64(0);
275 }
276 
277 static inline Int128 int128_one(void)
278 {
279     return int128_make64(1);
280 }
281 
282 static inline Int128 int128_2_64(void)
283 {
284     return int128_make128(0, 1);
285 }
286 
287 static inline Int128 int128_exts64(int64_t a)
288 {
289     return int128_make128(a, (a < 0) ? -1 : 0);
290 }
291 
292 static inline Int128 int128_not(Int128 a)
293 {
294     return int128_make128(~a.lo, ~a.hi);
295 }
296 
297 static inline Int128 int128_and(Int128 a, Int128 b)
298 {
299     return int128_make128(a.lo & b.lo, a.hi & b.hi);
300 }
301 
302 static inline Int128 int128_or(Int128 a, Int128 b)
303 {
304     return int128_make128(a.lo | b.lo, a.hi | b.hi);
305 }
306 
307 static inline Int128 int128_xor(Int128 a, Int128 b)
308 {
309     return int128_make128(a.lo ^ b.lo, a.hi ^ b.hi);
310 }
311 
312 static 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 
326 static 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 
340 static 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 
351 static inline Int128 int128_add(Int128 a, Int128 b)
352 {
353     uint64_t lo = a.lo + b.lo;
354 
355     /* a.lo <= a.lo + b.lo < a.lo + k (k is the base, 2^64).  Hence,
356      * a.lo + b.lo >= k implies 0 <= lo = a.lo + b.lo - k < a.lo.
357      * Similarly, a.lo + b.lo < k implies a.lo <= lo = a.lo + b.lo < k.
358      *
359      * So the carry is lo < a.lo.
360      */
361     return int128_make128(lo, (uint64_t)a.hi + b.hi + (lo < a.lo));
362 }
363 
364 static 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 
370 static 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 
375 static inline bool int128_nonneg(Int128 a)
376 {
377     return a.hi >= 0;
378 }
379 
380 static inline bool int128_eq(Int128 a, Int128 b)
381 {
382     return a.lo == b.lo && a.hi == b.hi;
383 }
384 
385 static inline bool int128_ne(Int128 a, Int128 b)
386 {
387     return !int128_eq(a, b);
388 }
389 
390 static 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 
395 static 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 
400 static inline bool int128_lt(Int128 a, Int128 b)
401 {
402     return !int128_ge(a, b);
403 }
404 
405 static inline bool int128_ult(Int128 a, Int128 b)
406 {
407     return !int128_uge(a, b);
408 }
409 
410 static inline bool int128_le(Int128 a, Int128 b)
411 {
412     return int128_ge(b, a);
413 }
414 
415 static inline bool int128_gt(Int128 a, Int128 b)
416 {
417     return !int128_le(a, b);
418 }
419 
420 static inline bool int128_nz(Int128 a)
421 {
422     return a.lo || a.hi;
423 }
424 
425 static inline Int128 int128_min(Int128 a, Int128 b)
426 {
427     return int128_le(a, b) ? a : b;
428 }
429 
430 static inline Int128 int128_max(Int128 a, Int128 b)
431 {
432     return int128_ge(a, b) ? a : b;
433 }
434 
435 static inline void int128_addto(Int128 *a, Int128 b)
436 {
437     *a = int128_add(*a, b);
438 }
439 
440 static inline void int128_subfrom(Int128 *a, Int128 b)
441 {
442     *a = int128_sub(*a, b);
443 }
444 
445 static inline Int128 bswap128(Int128 a)
446 {
447     return int128_make128(bswap64(a.hi), bswap64(a.lo));
448 }
449 
450 static 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 
459 Int128 int128_divu(Int128, Int128);
460 Int128 int128_remu(Int128, Int128);
461 Int128 int128_divs(Int128, Int128);
462 Int128 int128_rems(Int128, Int128);
463 
464 #endif /* CONFIG_INT128 */
465 
466 static 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 /* INT128_H */
476