1212 * ======================================================================================
1313 */
1414
15+ #include < cstdint>
1516#include < libutil/Math.hpp>
1617
17- #ifdef __SIZEOF_INT128__
18+ namespace {
19+ [[nodiscard, gnu::const , maybe_unused]] auto mul_hi64_fallback (
20+ const uint64_t first, const uint64_t second) noexcept
21+ -> uint64_t
22+ {
23+ auto get_lo_32_bits = [](const uint64_t value) noexcept {
24+ return static_cast <uint64_t >(static_cast <std::uint32_t >(value));
25+ };
26+
27+ auto get_hi_32_bits = [](const uint64_t value) noexcept {
28+ return static_cast <uint64_t >(value >> UINT64_C (32 ));
29+ };
30+
31+ const auto a_lo = get_lo_32_bits (first);
32+ const auto a_hi = get_hi_32_bits (first);
33+
34+ const auto b_lo = get_lo_32_bits (second);
35+ const auto b_hi = get_hi_32_bits (second);
36+
37+ const auto c_1 = get_hi_32_bits (a_lo * b_lo);
38+ const auto c_2 = (a_hi * b_lo) + c_1;
39+ const auto c_3 = (a_lo * b_hi) + get_lo_32_bits (c_2);
1840
19- # include < cstdint>
41+ return (a_hi * b_hi) + get_hi_32_bits (c_2) + get_hi_32_bits (c_3);
42+ }
43+ } // namespace
44+
45+ #ifdef __SIZEOF_INT128__
2046
2147namespace util ::math {
2248
@@ -67,9 +93,6 @@ auto mul_hi64(
6793} // namespace util::math
6894
6995#else
70-
71- # include < cstdint>
72-
7396# warning "No optimized version of mul_hi64() is available, using fallback"
7497
7598namespace util ::math {
@@ -78,21 +101,7 @@ auto mul_hi64(
78101 const uint64_t first, const uint64_t second) noexcept
79102 -> uint64_t
80103{
81- auto get_lo_32_bits = [](const uint64_t value) {
82- return static_cast <uint64_t >(static_cast <std::uint32_t >(value));
83- };
84-
85- const auto a_lo = get_lo_32_bits (first);
86- const auto a_hi = first >> 32uz;
87-
88- const auto b_lo = get_lo_32_bits (second);
89- const auto b_hi = second >> 32uz;
90-
91- const auto c_1 = (a_lo * b_lo) >> 32uz;
92- const auto c_2 = (a_hi * b_lo) + c_1;
93- const auto c_3 = (a_lo * b_hi) + get_lo_32_bits (c_2);
94-
95- return (a_hi * b_hi) + (c_2 >> 32uz) + (c_3 >> 32uz);
104+ return mul_hi64_fallback (first, second);
96105}
97106
98107} // namespace util::math
0 commit comments