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