15615 {
15616 static_assert(kPrecision == 64, "internal error");
15617
15618
15619
15620
15621
15622
15623
15624
15625
15626
15627
15628
15629
15630
15631
15632
15633
15634
15635
15636
15637
15638 const std::uint64_t u_lo = x.f & 0xFFFFFFFFu;
15639 const std::uint64_t u_hi = x.f >> 32u;
15640 const std::uint64_t v_lo = y.f & 0xFFFFFFFFu;
15641 const std::uint64_t v_hi = y.f >> 32u;
15642 const std::uint64_t p0 = u_lo * v_lo;
15643 const std::uint64_t p1 = u_lo * v_hi;
15644 const std::uint64_t p2 = u_hi * v_lo;
15645 const std::uint64_t p3 = u_hi * v_hi;
15646 const std::uint64_t p0_hi = p0 >> 32u;
15647 const std::uint64_t p1_lo = p1 & 0xFFFFFFFFu;
15648 const std::uint64_t p1_hi = p1 >> 32u;
15649 const std::uint64_t p2_lo = p2 & 0xFFFFFFFFu;
15650 const std::uint64_t p2_hi = p2 >> 32u;
15651 std::uint64_t Q = p0_hi + p1_lo + p2_lo;
15652
15653
15654
15655
15656
15657
15658
15659
15660 Q += std::uint64_t{1} << (64u - 32u - 1u);
15661 const std::uint64_t h = p3 + p2_hi + p1_hi + (Q >> 32u);
15662 return {h, x.e + y.e + 64};
15663 }