softfloat: add float128_to_int128
[qemu/ar7.git] / include / qemu / int128.h
blobef71f56e3f509f7b4ec6bceca4a5d6ad38ca48b1
1 #ifndef INT128_H
2 #define INT128_H
4 #include "qemu/bswap.h"
6 #ifdef CONFIG_INT128
7 typedef __int128_t Int128;
9 static inline Int128 int128_make64(uint64_t a)
11 return a;
14 static inline Int128 int128_makes64(int64_t a)
16 return a;
19 static inline Int128 int128_make128(uint64_t lo, uint64_t hi)
21 return (__uint128_t)hi << 64 | lo;
24 static inline uint64_t int128_get64(Int128 a)
26 uint64_t r = a;
27 assert(r == a);
28 return r;
31 static inline uint64_t int128_getlo(Int128 a)
33 return a;
36 static inline int64_t int128_gethi(Int128 a)
38 return a >> 64;
41 static inline Int128 int128_zero(void)
43 return 0;
46 static inline Int128 int128_one(void)
48 return 1;
51 static inline Int128 int128_2_64(void)
53 return (Int128)1 << 64;
56 static inline Int128 int128_exts64(int64_t a)
58 return a;
61 static inline Int128 int128_not(Int128 a)
63 return ~a;
66 static inline Int128 int128_and(Int128 a, Int128 b)
68 return a & b;
71 static inline Int128 int128_or(Int128 a, Int128 b)
73 return a | b;
76 static inline Int128 int128_xor(Int128 a, Int128 b)
78 return a ^ b;
81 static inline Int128 int128_rshift(Int128 a, int n)
83 return a >> n;
86 static inline Int128 int128_urshift(Int128 a, int n)
88 return (__uint128_t)a >> n;
91 static inline Int128 int128_lshift(Int128 a, int n)
93 return a << n;
96 static inline Int128 int128_add(Int128 a, Int128 b)
98 return a + b;
101 static inline Int128 int128_neg(Int128 a)
103 return -a;
106 static inline Int128 int128_sub(Int128 a, Int128 b)
108 return a - b;
111 static inline bool int128_nonneg(Int128 a)
113 return a >= 0;
116 static inline bool int128_eq(Int128 a, Int128 b)
118 return a == b;
121 static inline bool int128_ne(Int128 a, Int128 b)
123 return a != b;
126 static inline bool int128_ge(Int128 a, Int128 b)
128 return a >= b;
131 static inline bool int128_lt(Int128 a, Int128 b)
133 return a < b;
136 static inline bool int128_le(Int128 a, Int128 b)
138 return a <= b;
141 static inline bool int128_gt(Int128 a, Int128 b)
143 return a > b;
146 static inline bool int128_nz(Int128 a)
148 return a != 0;
151 static inline Int128 int128_min(Int128 a, Int128 b)
153 return a < b ? a : b;
156 static inline Int128 int128_max(Int128 a, Int128 b)
158 return a > b ? a : b;
161 static inline void int128_addto(Int128 *a, Int128 b)
163 *a += b;
166 static inline void int128_subfrom(Int128 *a, Int128 b)
168 *a -= b;
171 static inline Int128 bswap128(Int128 a)
173 #if __has_builtin(__builtin_bswap128)
174 return __builtin_bswap128(a);
175 #else
176 return int128_make128(bswap64(int128_gethi(a)), bswap64(int128_getlo(a)));
177 #endif
180 static inline Int128 int128_divu(Int128 a, Int128 b)
182 return (__uint128_t)a / (__uint128_t)b;
185 static inline Int128 int128_remu(Int128 a, Int128 b)
187 return (__uint128_t)a % (__uint128_t)b;
190 static inline Int128 int128_divs(Int128 a, Int128 b)
192 return a / b;
195 static inline Int128 int128_rems(Int128 a, Int128 b)
197 return a % b;
200 #else /* !CONFIG_INT128 */
202 typedef struct Int128 Int128;
205 * We guarantee that the in-memory byte representation of an
206 * Int128 is that of a host-endian-order 128-bit integer
207 * (whether using this struct or the __int128_t version of the type).
208 * Some code using this type relies on this (eg when copying it into
209 * guest memory or a gdb protocol buffer, or by using Int128 in
210 * a union with other integer types).
212 struct Int128 {
213 #if HOST_BIG_ENDIAN
214 int64_t hi;
215 uint64_t lo;
216 #else
217 uint64_t lo;
218 int64_t hi;
219 #endif
222 static inline Int128 int128_make64(uint64_t a)
224 return (Int128) { .lo = a, .hi = 0 };
227 static inline Int128 int128_makes64(int64_t a)
229 return (Int128) { .lo = a, .hi = a >> 63 };
232 static inline Int128 int128_make128(uint64_t lo, uint64_t hi)
234 return (Int128) { .lo = lo, .hi = hi };
237 static inline uint64_t int128_get64(Int128 a)
239 assert(!a.hi);
240 return a.lo;
243 static inline uint64_t int128_getlo(Int128 a)
245 return a.lo;
248 static inline int64_t int128_gethi(Int128 a)
250 return a.hi;
253 static inline Int128 int128_zero(void)
255 return int128_make64(0);
258 static inline Int128 int128_one(void)
260 return int128_make64(1);
263 static inline Int128 int128_2_64(void)
265 return int128_make128(0, 1);
268 static inline Int128 int128_exts64(int64_t a)
270 return int128_make128(a, (a < 0) ? -1 : 0);
273 static inline Int128 int128_not(Int128 a)
275 return int128_make128(~a.lo, ~a.hi);
278 static inline Int128 int128_and(Int128 a, Int128 b)
280 return int128_make128(a.lo & b.lo, a.hi & b.hi);
283 static inline Int128 int128_or(Int128 a, Int128 b)
285 return int128_make128(a.lo | b.lo, a.hi | b.hi);
288 static inline Int128 int128_xor(Int128 a, Int128 b)
290 return int128_make128(a.lo ^ b.lo, a.hi ^ b.hi);
293 static inline Int128 int128_rshift(Int128 a, int n)
295 int64_t h;
296 if (!n) {
297 return a;
299 h = a.hi >> (n & 63);
300 if (n >= 64) {
301 return int128_make128(h, h >> 63);
302 } else {
303 return int128_make128((a.lo >> n) | ((uint64_t)a.hi << (64 - n)), h);
307 static inline Int128 int128_urshift(Int128 a, int n)
309 uint64_t h = a.hi;
310 if (!n) {
311 return a;
313 h = h >> (n & 63);
314 if (n >= 64) {
315 return int128_make64(h);
316 } else {
317 return int128_make128((a.lo >> n) | ((uint64_t)a.hi << (64 - n)), h);
321 static inline Int128 int128_lshift(Int128 a, int n)
323 uint64_t l = a.lo << (n & 63);
324 if (n >= 64) {
325 return int128_make128(0, l);
326 } else if (n > 0) {
327 return int128_make128(l, (a.hi << n) | (a.lo >> (64 - n)));
329 return a;
332 static inline Int128 int128_add(Int128 a, Int128 b)
334 uint64_t lo = a.lo + b.lo;
336 /* a.lo <= a.lo + b.lo < a.lo + k (k is the base, 2^64). Hence,
337 * a.lo + b.lo >= k implies 0 <= lo = a.lo + b.lo - k < a.lo.
338 * Similarly, a.lo + b.lo < k implies a.lo <= lo = a.lo + b.lo < k.
340 * So the carry is lo < a.lo.
342 return int128_make128(lo, (uint64_t)a.hi + b.hi + (lo < a.lo));
345 static inline Int128 int128_neg(Int128 a)
347 uint64_t lo = -a.lo;
348 return int128_make128(lo, ~(uint64_t)a.hi + !lo);
351 static inline Int128 int128_sub(Int128 a, Int128 b)
353 return int128_make128(a.lo - b.lo, (uint64_t)a.hi - b.hi - (a.lo < b.lo));
356 static inline bool int128_nonneg(Int128 a)
358 return a.hi >= 0;
361 static inline bool int128_eq(Int128 a, Int128 b)
363 return a.lo == b.lo && a.hi == b.hi;
366 static inline bool int128_ne(Int128 a, Int128 b)
368 return !int128_eq(a, b);
371 static inline bool int128_ge(Int128 a, Int128 b)
373 return a.hi > b.hi || (a.hi == b.hi && a.lo >= b.lo);
376 static inline bool int128_lt(Int128 a, Int128 b)
378 return !int128_ge(a, b);
381 static inline bool int128_le(Int128 a, Int128 b)
383 return int128_ge(b, a);
386 static inline bool int128_gt(Int128 a, Int128 b)
388 return !int128_le(a, b);
391 static inline bool int128_nz(Int128 a)
393 return a.lo || a.hi;
396 static inline Int128 int128_min(Int128 a, Int128 b)
398 return int128_le(a, b) ? a : b;
401 static inline Int128 int128_max(Int128 a, Int128 b)
403 return int128_ge(a, b) ? a : b;
406 static inline void int128_addto(Int128 *a, Int128 b)
408 *a = int128_add(*a, b);
411 static inline void int128_subfrom(Int128 *a, Int128 b)
413 *a = int128_sub(*a, b);
416 static inline Int128 bswap128(Int128 a)
418 return int128_make128(bswap64(a.hi), bswap64(a.lo));
421 Int128 int128_divu(Int128, Int128);
422 Int128 int128_remu(Int128, Int128);
423 Int128 int128_divs(Int128, Int128);
424 Int128 int128_rems(Int128, Int128);
426 #endif /* CONFIG_INT128 */
428 static inline void bswap128s(Int128 *s)
430 *s = bswap128(*s);
433 #define UINT128_MAX int128_make128(~0LL, ~0LL)
434 #define INT128_MAX int128_make128(UINT64_MAX, INT64_MAX)
435 #define INT128_MIN int128_make128(0, INT64_MIN)
437 #endif /* INT128_H */