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