5 #include "qemu/bswap.h"
7 typedef __int128_t Int128
;
9 static inline Int128
int128_make64(uint64_t a
)
14 static inline Int128
int128_make128(uint64_t lo
, uint64_t hi
)
16 return (__uint128_t
)hi
<< 64 | lo
;
19 static inline uint64_t int128_get64(Int128 a
)
26 static inline uint64_t int128_getlo(Int128 a
)
31 static inline int64_t int128_gethi(Int128 a
)
36 static inline Int128
int128_zero(void)
41 static inline Int128
int128_one(void)
46 static inline Int128
int128_2_64(void)
48 return (Int128
)1 << 64;
51 static inline Int128
int128_exts64(int64_t a
)
56 static inline Int128
int128_and(Int128 a
, Int128 b
)
61 static inline Int128
int128_rshift(Int128 a
, int n
)
66 static inline Int128
int128_add(Int128 a
, Int128 b
)
71 static inline Int128
int128_neg(Int128 a
)
76 static inline Int128
int128_sub(Int128 a
, Int128 b
)
81 static inline bool int128_nonneg(Int128 a
)
86 static inline bool int128_eq(Int128 a
, Int128 b
)
91 static inline bool int128_ne(Int128 a
, Int128 b
)
96 static inline bool int128_ge(Int128 a
, Int128 b
)
101 static inline bool int128_lt(Int128 a
, Int128 b
)
106 static inline bool int128_le(Int128 a
, Int128 b
)
111 static inline bool int128_gt(Int128 a
, Int128 b
)
116 static inline bool int128_nz(Int128 a
)
121 static inline Int128
int128_min(Int128 a
, Int128 b
)
123 return a
< b
? a
: b
;
126 static inline Int128
int128_max(Int128 a
, Int128 b
)
128 return a
> b
? a
: b
;
131 static inline void int128_addto(Int128
*a
, Int128 b
)
136 static inline void int128_subfrom(Int128
*a
, Int128 b
)
141 static inline Int128
bswap128(Int128 a
)
143 return int128_make128(bswap64(int128_gethi(a
)), bswap64(int128_getlo(a
)));
146 #else /* !CONFIG_INT128 */
148 typedef struct Int128 Int128
;
155 static inline Int128
int128_make64(uint64_t a
)
157 return (Int128
) { a
, 0 };
160 static inline Int128
int128_make128(uint64_t lo
, uint64_t hi
)
162 return (Int128
) { lo
, hi
};
165 static inline uint64_t int128_get64(Int128 a
)
171 static inline uint64_t int128_getlo(Int128 a
)
176 static inline int64_t int128_gethi(Int128 a
)
181 static inline Int128
int128_zero(void)
183 return int128_make64(0);
186 static inline Int128
int128_one(void)
188 return int128_make64(1);
191 static inline Int128
int128_2_64(void)
193 return (Int128
) { 0, 1 };
196 static inline Int128
int128_exts64(int64_t a
)
198 return (Int128
) { .lo
= a
, .hi
= (a
< 0) ? -1 : 0 };
201 static inline Int128
int128_and(Int128 a
, Int128 b
)
203 return (Int128
) { a
.lo
& b
.lo
, a
.hi
& b
.hi
};
206 static inline Int128
int128_rshift(Int128 a
, int n
)
212 h
= a
.hi
>> (n
& 63);
214 return int128_make128(h
, h
>> 63);
216 return int128_make128((a
.lo
>> n
) | ((uint64_t)a
.hi
<< (64 - n
)), h
);
220 static inline Int128
int128_add(Int128 a
, Int128 b
)
222 uint64_t lo
= a
.lo
+ b
.lo
;
224 /* a.lo <= a.lo + b.lo < a.lo + k (k is the base, 2^64). Hence,
225 * a.lo + b.lo >= k implies 0 <= lo = a.lo + b.lo - k < a.lo.
226 * Similarly, a.lo + b.lo < k implies a.lo <= lo = a.lo + b.lo < k.
228 * So the carry is lo < a.lo.
230 return int128_make128(lo
, (uint64_t)a
.hi
+ b
.hi
+ (lo
< a
.lo
));
233 static inline Int128
int128_neg(Int128 a
)
236 return int128_make128(lo
, ~(uint64_t)a
.hi
+ !lo
);
239 static inline Int128
int128_sub(Int128 a
, Int128 b
)
241 return int128_make128(a
.lo
- b
.lo
, (uint64_t)a
.hi
- b
.hi
- (a
.lo
< b
.lo
));
244 static inline bool int128_nonneg(Int128 a
)
249 static inline bool int128_eq(Int128 a
, Int128 b
)
251 return a
.lo
== b
.lo
&& a
.hi
== b
.hi
;
254 static inline bool int128_ne(Int128 a
, Int128 b
)
256 return !int128_eq(a
, b
);
259 static inline bool int128_ge(Int128 a
, Int128 b
)
261 return a
.hi
> b
.hi
|| (a
.hi
== b
.hi
&& a
.lo
>= b
.lo
);
264 static inline bool int128_lt(Int128 a
, Int128 b
)
266 return !int128_ge(a
, b
);
269 static inline bool int128_le(Int128 a
, Int128 b
)
271 return int128_ge(b
, a
);
274 static inline bool int128_gt(Int128 a
, Int128 b
)
276 return !int128_le(a
, b
);
279 static inline bool int128_nz(Int128 a
)
284 static inline Int128
int128_min(Int128 a
, Int128 b
)
286 return int128_le(a
, b
) ? a
: b
;
289 static inline Int128
int128_max(Int128 a
, Int128 b
)
291 return int128_ge(a
, b
) ? a
: b
;
294 static inline void int128_addto(Int128
*a
, Int128 b
)
296 *a
= int128_add(*a
, b
);
299 static inline void int128_subfrom(Int128
*a
, Int128 b
)
301 *a
= int128_sub(*a
, b
);
304 #endif /* CONFIG_INT128 */
305 #endif /* INT128_H */