int128.h (6543B)
1#ifndef INT128_H 2#define INT128_H 3 4#include "qemu/bswap.h" 5 6#ifdef CONFIG_INT128 7typedef __int128_t Int128; 8 9static inline Int128 int128_make64(uint64_t a) 10{ 11 return a; 12} 13 14static inline Int128 int128_makes64(int64_t a) 15{ 16 return a; 17} 18 19static inline Int128 int128_make128(uint64_t lo, uint64_t hi) 20{ 21 return (__uint128_t)hi << 64 | lo; 22} 23 24static inline uint64_t int128_get64(Int128 a) 25{ 26 uint64_t r = a; 27 assert(r == a); 28 return r; 29} 30 31static inline uint64_t int128_getlo(Int128 a) 32{ 33 return a; 34} 35 36static inline int64_t int128_gethi(Int128 a) 37{ 38 return a >> 64; 39} 40 41static inline Int128 int128_zero(void) 42{ 43 return 0; 44} 45 46static inline Int128 int128_one(void) 47{ 48 return 1; 49} 50 51static inline Int128 int128_2_64(void) 52{ 53 return (Int128)1 << 64; 54} 55 56static inline Int128 int128_exts64(int64_t a) 57{ 58 return a; 59} 60 61static inline Int128 int128_and(Int128 a, Int128 b) 62{ 63 return a & b; 64} 65 66static inline Int128 int128_or(Int128 a, Int128 b) 67{ 68 return a | b; 69} 70 71static inline Int128 int128_rshift(Int128 a, int n) 72{ 73 return a >> n; 74} 75 76static inline Int128 int128_lshift(Int128 a, int n) 77{ 78 return a << n; 79} 80 81static inline Int128 int128_add(Int128 a, Int128 b) 82{ 83 return a + b; 84} 85 86static inline Int128 int128_neg(Int128 a) 87{ 88 return -a; 89} 90 91static inline Int128 int128_sub(Int128 a, Int128 b) 92{ 93 return a - b; 94} 95 96static inline bool int128_nonneg(Int128 a) 97{ 98 return a >= 0; 99} 100 101static inline bool int128_eq(Int128 a, Int128 b) 102{ 103 return a == b; 104} 105 106static inline bool int128_ne(Int128 a, Int128 b) 107{ 108 return a != b; 109} 110 111static inline bool int128_ge(Int128 a, Int128 b) 112{ 113 return a >= b; 114} 115 116static inline bool int128_lt(Int128 a, Int128 b) 117{ 118 return a < b; 119} 120 121static inline bool int128_le(Int128 a, Int128 b) 122{ 123 return a <= b; 124} 125 126static inline bool int128_gt(Int128 a, Int128 b) 127{ 128 return a > b; 129} 130 131static inline bool int128_nz(Int128 a) 132{ 133 return a != 0; 134} 135 136static inline Int128 int128_min(Int128 a, Int128 b) 137{ 138 return a < b ? a : b; 139} 140 141static inline Int128 int128_max(Int128 a, Int128 b) 142{ 143 return a > b ? a : b; 144} 145 146static inline void int128_addto(Int128 *a, Int128 b) 147{ 148 *a += b; 149} 150 151static inline void int128_subfrom(Int128 *a, Int128 b) 152{ 153 *a -= b; 154} 155 156static inline Int128 bswap128(Int128 a) 157{ 158#if __has_builtin(__builtin_bswap128) 159 return __builtin_bswap128(a); 160#else 161 return int128_make128(bswap64(int128_gethi(a)), bswap64(int128_getlo(a))); 162#endif 163} 164 165#else /* !CONFIG_INT128 */ 166 167typedef struct Int128 Int128; 168 169/* 170 * We guarantee that the in-memory byte representation of an 171 * Int128 is that of a host-endian-order 128-bit integer 172 * (whether using this struct or the __int128_t version of the type). 173 * Some code using this type relies on this (eg when copying it into 174 * guest memory or a gdb protocol buffer, or by using Int128 in 175 * a union with other integer types). 176 */ 177struct Int128 { 178#ifdef HOST_WORDS_BIGENDIAN 179 int64_t hi; 180 uint64_t lo; 181#else 182 uint64_t lo; 183 int64_t hi; 184#endif 185}; 186 187static inline Int128 int128_make64(uint64_t a) 188{ 189 return (Int128) { .lo = a, .hi = 0 }; 190} 191 192static inline Int128 int128_makes64(int64_t a) 193{ 194 return (Int128) { .lo = a, .hi = a >> 63 }; 195} 196 197static inline Int128 int128_make128(uint64_t lo, uint64_t hi) 198{ 199 return (Int128) { .lo = lo, .hi = hi }; 200} 201 202static inline uint64_t int128_get64(Int128 a) 203{ 204 assert(!a.hi); 205 return a.lo; 206} 207 208static inline uint64_t int128_getlo(Int128 a) 209{ 210 return a.lo; 211} 212 213static inline int64_t int128_gethi(Int128 a) 214{ 215 return a.hi; 216} 217 218static inline Int128 int128_zero(void) 219{ 220 return int128_make64(0); 221} 222 223static inline Int128 int128_one(void) 224{ 225 return int128_make64(1); 226} 227 228static inline Int128 int128_2_64(void) 229{ 230 return int128_make128(0, 1); 231} 232 233static inline Int128 int128_exts64(int64_t a) 234{ 235 return int128_make128(a, (a < 0) ? -1 : 0); 236} 237 238static inline Int128 int128_and(Int128 a, Int128 b) 239{ 240 return int128_make128(a.lo & b.lo, a.hi & b.hi); 241} 242 243static inline Int128 int128_or(Int128 a, Int128 b) 244{ 245 return int128_make128(a.lo | b.lo, a.hi | b.hi); 246} 247 248static inline Int128 int128_rshift(Int128 a, int n) 249{ 250 int64_t h; 251 if (!n) { 252 return a; 253 } 254 h = a.hi >> (n & 63); 255 if (n >= 64) { 256 return int128_make128(h, h >> 63); 257 } else { 258 return int128_make128((a.lo >> n) | ((uint64_t)a.hi << (64 - n)), h); 259 } 260} 261 262static inline Int128 int128_lshift(Int128 a, int n) 263{ 264 uint64_t l = a.lo << (n & 63); 265 if (n >= 64) { 266 return int128_make128(0, l); 267 } else if (n > 0) { 268 return int128_make128(l, (a.hi << n) | (a.lo >> (64 - n))); 269 } 270 return a; 271} 272 273static inline Int128 int128_add(Int128 a, Int128 b) 274{ 275 uint64_t lo = a.lo + b.lo; 276 277 /* a.lo <= a.lo + b.lo < a.lo + k (k is the base, 2^64). Hence, 278 * a.lo + b.lo >= k implies 0 <= lo = a.lo + b.lo - k < a.lo. 279 * Similarly, a.lo + b.lo < k implies a.lo <= lo = a.lo + b.lo < k. 280 * 281 * So the carry is lo < a.lo. 282 */ 283 return int128_make128(lo, (uint64_t)a.hi + b.hi + (lo < a.lo)); 284} 285 286static inline Int128 int128_neg(Int128 a) 287{ 288 uint64_t lo = -a.lo; 289 return int128_make128(lo, ~(uint64_t)a.hi + !lo); 290} 291 292static inline Int128 int128_sub(Int128 a, Int128 b) 293{ 294 return int128_make128(a.lo - b.lo, (uint64_t)a.hi - b.hi - (a.lo < b.lo)); 295} 296 297static inline bool int128_nonneg(Int128 a) 298{ 299 return a.hi >= 0; 300} 301 302static inline bool int128_eq(Int128 a, Int128 b) 303{ 304 return a.lo == b.lo && a.hi == b.hi; 305} 306 307static inline bool int128_ne(Int128 a, Int128 b) 308{ 309 return !int128_eq(a, b); 310} 311 312static inline bool int128_ge(Int128 a, Int128 b) 313{ 314 return a.hi > b.hi || (a.hi == b.hi && a.lo >= b.lo); 315} 316 317static inline bool int128_lt(Int128 a, Int128 b) 318{ 319 return !int128_ge(a, b); 320} 321 322static inline bool int128_le(Int128 a, Int128 b) 323{ 324 return int128_ge(b, a); 325} 326 327static inline bool int128_gt(Int128 a, Int128 b) 328{ 329 return !int128_le(a, b); 330} 331 332static inline bool int128_nz(Int128 a) 333{ 334 return a.lo || a.hi; 335} 336 337static inline Int128 int128_min(Int128 a, Int128 b) 338{ 339 return int128_le(a, b) ? a : b; 340} 341 342static inline Int128 int128_max(Int128 a, Int128 b) 343{ 344 return int128_ge(a, b) ? a : b; 345} 346 347static inline void int128_addto(Int128 *a, Int128 b) 348{ 349 *a = int128_add(*a, b); 350} 351 352static inline void int128_subfrom(Int128 *a, Int128 b) 353{ 354 *a = int128_sub(*a, b); 355} 356 357static inline Int128 bswap128(Int128 a) 358{ 359 return int128_make128(bswap64(a.hi), bswap64(a.lo)); 360} 361 362#endif /* CONFIG_INT128 */ 363 364static inline void bswap128s(Int128 *s) 365{ 366 *s = bswap128(*s); 367} 368 369#endif /* INT128_H */