| 256 | } |
| 257 | |
| 258 | static inline int64_t libdivide_mullhi_s64(int64_t x, int64_t y) { |
| 259 | #if defined(LIBDIVIDE_VC) && \ |
| 260 | defined(LIBDIVIDE_X86_64) |
| 261 | return __mulh(x, y); |
| 262 | #elif defined(HAS_INT128_T) |
| 263 | __int128_t xl = x, yl = y; |
| 264 | __int128_t rl = xl * yl; |
| 265 | return (int64_t)(rl >> 64); |
| 266 | #else |
| 267 | // full 128 bits are x0 * y0 + (x0 * y1 << 32) + (x1 * y0 << 32) + (x1 * y1 << 64) |
| 268 | uint32_t mask = 0xFFFFFFFF; |
| 269 | uint32_t x0 = (uint32_t)(x & mask); |
| 270 | uint32_t y0 = (uint32_t)(y & mask); |
| 271 | int32_t x1 = (int32_t)(x >> 32); |
| 272 | int32_t y1 = (int32_t)(y >> 32); |
| 273 | uint32_t x0y0_hi = libdivide_mullhi_u32(x0, y0); |
| 274 | int64_t t = x1 * (int64_t)y0 + x0y0_hi; |
| 275 | int64_t w1 = x0 * (int64_t)y1 + (t & mask); |
| 276 | |
| 277 | return x1 * (int64_t)y1 + (t >> 32) + (w1 >> 32); |
| 278 | #endif |
| 279 | } |
| 280 | |
| 281 | static inline int32_t libdivide_count_leading_zeros32(uint32_t val) { |
| 282 | #if defined(__GNUC__) || \ |
no test coverage detected