]> Git Repo - qemu.git/blame - include/qemu/int128.h
target/arm: Implement an IMPDEF pauth algorithm
[qemu.git] / include / qemu / int128.h
CommitLineData
b7cd3db6
AK
1#ifndef INT128_H
2#define INT128_H
3
0846beb3 4#ifdef CONFIG_INT128
7ebee43e 5#include "qemu/bswap.h"
0846beb3
RH
6
7typedef __int128_t Int128;
8
9static inline Int128 int128_make64(uint64_t a)
10{
11 return a;
12}
13
1edaeee0
RH
14static inline Int128 int128_make128(uint64_t lo, uint64_t hi)
15{
16 return (__uint128_t)hi << 64 | lo;
17}
18
0846beb3
RH
19static inline uint64_t int128_get64(Int128 a)
20{
21 uint64_t r = a;
22 assert(r == a);
23 return r;
24}
25
26static inline uint64_t int128_getlo(Int128 a)
27{
28 return a;
29}
30
31static inline int64_t int128_gethi(Int128 a)
32{
33 return a >> 64;
34}
35
36static inline Int128 int128_zero(void)
37{
38 return 0;
39}
40
41static inline Int128 int128_one(void)
42{
43 return 1;
44}
45
46static inline Int128 int128_2_64(void)
47{
48 return (Int128)1 << 64;
49}
50
51static inline Int128 int128_exts64(int64_t a)
52{
53 return a;
54}
55
56static inline Int128 int128_and(Int128 a, Int128 b)
57{
58 return a & b;
59}
60
61static inline Int128 int128_rshift(Int128 a, int n)
62{
63 return a >> n;
64}
65
5be4dd04
RH
66static inline Int128 int128_lshift(Int128 a, int n)
67{
68 return a << n;
69}
70
0846beb3
RH
71static inline Int128 int128_add(Int128 a, Int128 b)
72{
73 return a + b;
74}
75
76static inline Int128 int128_neg(Int128 a)
77{
78 return -a;
79}
80
81static inline Int128 int128_sub(Int128 a, Int128 b)
82{
83 return a - b;
84}
85
86static inline bool int128_nonneg(Int128 a)
87{
88 return a >= 0;
89}
90
91static inline bool int128_eq(Int128 a, Int128 b)
92{
93 return a == b;
94}
95
96static inline bool int128_ne(Int128 a, Int128 b)
97{
98 return a != b;
99}
100
101static inline bool int128_ge(Int128 a, Int128 b)
102{
103 return a >= b;
104}
105
106static inline bool int128_lt(Int128 a, Int128 b)
107{
108 return a < b;
109}
110
111static inline bool int128_le(Int128 a, Int128 b)
112{
113 return a <= b;
114}
115
116static inline bool int128_gt(Int128 a, Int128 b)
117{
118 return a > b;
119}
120
121static inline bool int128_nz(Int128 a)
122{
123 return a != 0;
124}
125
126static inline Int128 int128_min(Int128 a, Int128 b)
127{
128 return a < b ? a : b;
129}
130
131static inline Int128 int128_max(Int128 a, Int128 b)
132{
133 return a > b ? a : b;
134}
135
136static inline void int128_addto(Int128 *a, Int128 b)
137{
138 *a += b;
139}
140
141static inline void int128_subfrom(Int128 *a, Int128 b)
142{
143 *a -= b;
144}
145
7ebee43e
RH
146static inline Int128 bswap128(Int128 a)
147{
148 return int128_make128(bswap64(int128_gethi(a)), bswap64(int128_getlo(a)));
149}
150
0846beb3 151#else /* !CONFIG_INT128 */
6046c620 152
b7cd3db6
AK
153typedef struct Int128 Int128;
154
155struct Int128 {
156 uint64_t lo;
157 int64_t hi;
158};
159
160static inline Int128 int128_make64(uint64_t a)
161{
162 return (Int128) { a, 0 };
163}
164
1edaeee0
RH
165static inline Int128 int128_make128(uint64_t lo, uint64_t hi)
166{
167 return (Int128) { lo, hi };
168}
169
b7cd3db6
AK
170static inline uint64_t int128_get64(Int128 a)
171{
172 assert(!a.hi);
173 return a.lo;
174}
175
258dfaaa
RH
176static inline uint64_t int128_getlo(Int128 a)
177{
178 return a.lo;
179}
180
181static inline int64_t int128_gethi(Int128 a)
182{
183 return a.hi;
184}
185
b7cd3db6
AK
186static inline Int128 int128_zero(void)
187{
188 return int128_make64(0);
189}
190
191static inline Int128 int128_one(void)
192{
193 return int128_make64(1);
194}
195
196static inline Int128 int128_2_64(void)
197{
198 return (Int128) { 0, 1 };
199}
200
12e1129b
AK
201static inline Int128 int128_exts64(int64_t a)
202{
203 return (Int128) { .lo = a, .hi = (a < 0) ? -1 : 0 };
204}
205
052e87b0
PB
206static inline Int128 int128_and(Int128 a, Int128 b)
207{
208 return (Int128) { a.lo & b.lo, a.hi & b.hi };
209}
210
211static inline Int128 int128_rshift(Int128 a, int n)
212{
213 int64_t h;
214 if (!n) {
215 return a;
216 }
217 h = a.hi >> (n & 63);
218 if (n >= 64) {
1edaeee0 219 return int128_make128(h, h >> 63);
052e87b0 220 } else {
1edaeee0 221 return int128_make128((a.lo >> n) | ((uint64_t)a.hi << (64 - n)), h);
052e87b0
PB
222 }
223}
224
5be4dd04
RH
225static inline Int128 int128_lshift(Int128 a, int n)
226{
227 uint64_t l = a.lo << (n & 63);
228 if (n >= 64) {
229 return int128_make128(0, l);
230 } else if (n > 0) {
231 return int128_make128(l, (a.hi << n) | (a.lo >> (64 - n)));
232 }
233 return a;
234}
235
b7cd3db6
AK
236static inline Int128 int128_add(Int128 a, Int128 b)
237{
6046c620
PB
238 uint64_t lo = a.lo + b.lo;
239
240 /* a.lo <= a.lo + b.lo < a.lo + k (k is the base, 2^64). Hence,
241 * a.lo + b.lo >= k implies 0 <= lo = a.lo + b.lo - k < a.lo.
242 * Similarly, a.lo + b.lo < k implies a.lo <= lo = a.lo + b.lo < k.
243 *
244 * So the carry is lo < a.lo.
245 */
1edaeee0 246 return int128_make128(lo, (uint64_t)a.hi + b.hi + (lo < a.lo));
b7cd3db6
AK
247}
248
249static inline Int128 int128_neg(Int128 a)
250{
6046c620 251 uint64_t lo = -a.lo;
1edaeee0 252 return int128_make128(lo, ~(uint64_t)a.hi + !lo);
b7cd3db6
AK
253}
254
255static inline Int128 int128_sub(Int128 a, Int128 b)
256{
1edaeee0 257 return int128_make128(a.lo - b.lo, (uint64_t)a.hi - b.hi - (a.lo < b.lo));
b7cd3db6
AK
258}
259
260static inline bool int128_nonneg(Int128 a)
261{
262 return a.hi >= 0;
263}
264
265static inline bool int128_eq(Int128 a, Int128 b)
266{
267 return a.lo == b.lo && a.hi == b.hi;
268}
269
270static inline bool int128_ne(Int128 a, Int128 b)
271{
272 return !int128_eq(a, b);
273}
274
275static inline bool int128_ge(Int128 a, Int128 b)
276{
6046c620 277 return a.hi > b.hi || (a.hi == b.hi && a.lo >= b.lo);
b7cd3db6
AK
278}
279
280static inline bool int128_lt(Int128 a, Int128 b)
281{
282 return !int128_ge(a, b);
283}
284
285static inline bool int128_le(Int128 a, Int128 b)
286{
287 return int128_ge(b, a);
288}
289
290static inline bool int128_gt(Int128 a, Int128 b)
291{
292 return !int128_le(a, b);
293}
294
295static inline bool int128_nz(Int128 a)
296{
297 return a.lo || a.hi;
298}
299
300static inline Int128 int128_min(Int128 a, Int128 b)
301{
302 return int128_le(a, b) ? a : b;
303}
304
305static inline Int128 int128_max(Int128 a, Int128 b)
306{
307 return int128_ge(a, b) ? a : b;
308}
309
310static inline void int128_addto(Int128 *a, Int128 b)
311{
312 *a = int128_add(*a, b);
313}
314
315static inline void int128_subfrom(Int128 *a, Int128 b)
316{
317 *a = int128_sub(*a, b);
318}
319
0846beb3
RH
320#endif /* CONFIG_INT128 */
321#endif /* INT128_H */
This page took 0.471226 seconds and 4 git commands to generate.