File indexing completed on 2025-01-18 09:30:23
0001
0002
0003
0004
0005 #ifndef BOOST_HASH_DETAIL_MULX_HPP
0006 #define BOOST_HASH_DETAIL_MULX_HPP
0007
0008 #include <cstdint>
0009 #if defined(_MSC_VER)
0010 # include <intrin.h>
0011 #endif
0012
0013 namespace boost
0014 {
0015 namespace hash_detail
0016 {
0017
0018 #if defined(_MSC_VER) && defined(_M_X64) && !defined(__clang__)
0019
0020 __forceinline std::uint64_t mulx( std::uint64_t x, std::uint64_t y )
0021 {
0022 std::uint64_t r2;
0023 std::uint64_t r = _umul128( x, y, &r2 );
0024 return r ^ r2;
0025 }
0026
0027 #elif defined(_MSC_VER) && defined(_M_ARM64) && !defined(__clang__)
0028
0029 __forceinline std::uint64_t mulx( std::uint64_t x, std::uint64_t y )
0030 {
0031 std::uint64_t r = x * y;
0032 std::uint64_t r2 = __umulh( x, y );
0033 return r ^ r2;
0034 }
0035
0036 #elif defined(__SIZEOF_INT128__)
0037
0038 inline std::uint64_t mulx( std::uint64_t x, std::uint64_t y )
0039 {
0040 __uint128_t r = static_cast<__uint128_t>( x ) * y;
0041 return static_cast<std::uint64_t>( r ) ^ static_cast<std::uint64_t>( r >> 64 );
0042 }
0043
0044 #else
0045
0046 inline std::uint64_t mulx( std::uint64_t x, std::uint64_t y )
0047 {
0048 std::uint64_t x1 = static_cast<std::uint32_t>( x );
0049 std::uint64_t x2 = x >> 32;
0050
0051 std::uint64_t y1 = static_cast<std::uint32_t>( y );
0052 std::uint64_t y2 = y >> 32;
0053
0054 std::uint64_t r3 = x2 * y2;
0055
0056 std::uint64_t r2a = x1 * y2;
0057
0058 r3 += r2a >> 32;
0059
0060 std::uint64_t r2b = x2 * y1;
0061
0062 r3 += r2b >> 32;
0063
0064 std::uint64_t r1 = x1 * y1;
0065
0066 std::uint64_t r2 = (r1 >> 32) + static_cast<std::uint32_t>( r2a ) + static_cast<std::uint32_t>( r2b );
0067
0068 r1 = (r2 << 32) + static_cast<std::uint32_t>( r1 );
0069 r3 += r2 >> 32;
0070
0071 return r1 ^ r3;
0072 }
0073
0074 #endif
0075
0076 }
0077 }
0078
0079 #endif