Multiply two 64 bit word components into a 128 bit result, with high bits stored in hi and low bits in lo.
| 531 | // Multiply two 64 bit word components into a 128 bit result, with high bits |
| 532 | // stored in hi and low bits in lo. |
| 533 | inline void ExtendAndMultiply(uint64_t x, uint64_t y, uint64_t* hi, uint64_t* lo) { |
| 534 | // Perform multiplication on two 64 bit words x and y into a 128 bit result |
| 535 | // by splitting up x and y into 32 bit high/low bit components, |
| 536 | // allowing us to represent the multiplication as |
| 537 | // x * y = x_lo * y_lo + x_hi * y_lo * 2^32 + y_hi * x_lo * 2^32 |
| 538 | // + x_hi * y_hi * 2^64 |
| 539 | // |
| 540 | // Now, consider the final output as lo_lo || lo_hi || hi_lo || hi_hi |
| 541 | // Therefore, |
| 542 | // lo_lo is (x_lo * y_lo)_lo, |
| 543 | // lo_hi is ((x_lo * y_lo)_hi + (x_hi * y_lo)_lo + (x_lo * y_hi)_lo)_lo, |
| 544 | // hi_lo is ((x_hi * y_hi)_lo + (x_hi * y_lo)_hi + (x_lo * y_hi)_hi)_hi, |
| 545 | // hi_hi is (x_hi * y_hi)_hi |
| 546 | const uint64_t x_lo = x & kInt32Mask; |
| 547 | const uint64_t y_lo = y & kInt32Mask; |
| 548 | const uint64_t x_hi = x >> 32; |
| 549 | const uint64_t y_hi = y >> 32; |
| 550 | |
| 551 | const uint64_t t = x_lo * y_lo; |
| 552 | const uint64_t t_lo = t & kInt32Mask; |
| 553 | const uint64_t t_hi = t >> 32; |
| 554 | |
| 555 | const uint64_t u = x_hi * y_lo + t_hi; |
| 556 | const uint64_t u_lo = u & kInt32Mask; |
| 557 | const uint64_t u_hi = u >> 32; |
| 558 | |
| 559 | const uint64_t v = x_lo * y_hi + u_lo; |
| 560 | const uint64_t v_hi = v >> 32; |
| 561 | |
| 562 | *hi = x_hi * y_hi + u_hi + v_hi; |
| 563 | *lo = (v << 32) + t_lo; |
| 564 | } |
| 565 | |
| 566 | struct uint128_t { |
| 567 | uint128_t() {} |