File indexing completed on 2026-08-17 08:39:06
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_BLOOM_DETAIL_MULX64_HPP
0011 #define BOOST_BLOOM_DETAIL_MULX64_HPP
0012
0013 #include <climits>
0014 #include <cstddef>
0015 #include <cstdint>
0016
0017 #if defined(_MSC_VER)&&!defined(__clang__)
0018 #include <intrin.h>
0019 #endif
0020
0021 namespace boost{
0022 namespace bloom{
0023 namespace detail{
0024
0025 #if defined(_MSC_VER)&&defined(_M_X64)&&!defined(__clang__)
0026
0027 __forceinline std::uint64_t umul128(
0028 std::uint64_t x,std::uint64_t y,std::uint64_t& hi)
0029 {
0030 return _umul128(x,y,&hi);
0031 }
0032
0033 #elif defined(_MSC_VER)&&defined(_M_ARM64)&&!defined(__clang__)
0034
0035 __forceinline std::uint64_t umul128(
0036 std::uint64_t x,std::uint64_t y,std::uint64_t& hi)
0037 {
0038 hi=__umulh(x,y);
0039 return x*y;
0040 }
0041
0042 #elif defined(__SIZEOF_INT128__)
0043
0044
0045 inline std::uint64_t umul128(
0046 std::uint64_t x,std::uint64_t y,std::uint64_t& hi)
0047 {
0048 __uint128_t r=(__uint128_t)x*y;
0049 hi=(std::uint64_t)(r>>64);
0050 return (std::uint64_t)r;
0051 }
0052
0053 #else
0054
0055
0056 inline std::uint64_t umul128(
0057 std::uint64_t x,std::uint64_t y,std::uint64_t& hi)
0058 {
0059 std::uint64_t x1=(std::uint32_t)x;
0060 std::uint64_t x2=x >> 32;
0061
0062 std::uint64_t y1=(std::uint32_t)y;
0063 std::uint64_t y2=y >> 32;
0064
0065 std::uint64_t r3=x2*y2;
0066
0067 std::uint64_t r2a=x1*y2;
0068
0069 r3+=r2a>>32;
0070
0071 std::uint64_t r2b=x2*y1;
0072
0073 r3+=r2b>>32;
0074
0075 std::uint64_t r1=x1*y1;
0076
0077 std::uint64_t r2=(r1>>32)+(std::uint32_t)r2a+(std::uint32_t)r2b;
0078
0079 r1=(r2<<32)+(std::uint32_t)r1;
0080 r3+=r2>>32;
0081
0082 hi=r3;
0083 return r1;
0084 }
0085
0086 #endif
0087
0088
0089 inline std::uint64_t mulx64(std::uint64_t x)noexcept
0090 {
0091
0092 std::uint64_t hi;
0093 std::uint64_t lo=umul128(x,0x9E3779B97F4A7C15ull,hi);
0094 return hi^lo;
0095 }
0096
0097 }
0098 }
0099 }
0100 #endif