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