| 229 | } |
| 230 | |
| 231 | static inline uint64_t libdivide_mullhi_u64(uint64_t x, uint64_t y) { |
| 232 | #if defined(LIBDIVIDE_VC) && \ |
| 233 | defined(LIBDIVIDE_X86_64) |
| 234 | return __umulh(x, y); |
| 235 | #elif defined(HAS_INT128_T) |
| 236 | __uint128_t xl = x, yl = y; |
| 237 | __uint128_t rl = xl * yl; |
| 238 | return (uint64_t)(rl >> 64); |
| 239 | #else |
| 240 | // full 128 bits are x0 * y0 + (x0 * y1 << 32) + (x1 * y0 << 32) + (x1 * y1 << 64) |
| 241 | uint32_t mask = 0xFFFFFFFF; |
| 242 | uint32_t x0 = (uint32_t)(x & mask); |
| 243 | uint32_t x1 = (uint32_t)(x >> 32); |
| 244 | uint32_t y0 = (uint32_t)(y & mask); |
| 245 | uint32_t y1 = (uint32_t)(y >> 32); |
| 246 | uint32_t x0y0_hi = libdivide_mullhi_u32(x0, y0); |
| 247 | uint64_t x0y1 = x0 * (uint64_t)y1; |
| 248 | uint64_t x1y0 = x1 * (uint64_t)y0; |
| 249 | uint64_t x1y1 = x1 * (uint64_t)y1; |
| 250 | uint64_t temp = x1y0 + x0y0_hi; |
| 251 | uint64_t temp_lo = temp & mask; |
| 252 | uint64_t temp_hi = temp >> 32; |
| 253 | |
| 254 | return x1y1 + temp_hi + ((temp_lo + x0y1) >> 32); |
| 255 | #endif |
| 256 | } |
| 257 | |
| 258 | static inline int64_t libdivide_mullhi_s64(int64_t x, int64_t y) { |
| 259 | #if defined(LIBDIVIDE_VC) && \ |
no test coverage detected