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