Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-08-17 08:39:06

0001 /* Copyright 2022 Peter Dimov.
0002  * Copyright 2025 Joaquin M Lopez Munoz.
0003  * Distributed under the Boost Software License, Version 1.0.
0004  * (See accompanying file LICENSE_1_0.txt or copy at
0005  * http://www.boost.org/LICENSE_1_0.txt)
0006  *
0007  * See https://www.boost.org/libs/bloom for library home page.
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 /* NOLINTNEXTLINE(readability-redundant-inline-specifier) */
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 /* NOLINTNEXTLINE(readability-redundant-inline-specifier) */
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 /* NOLINTNEXTLINE(readability-redundant-inline-specifier) */
0089 inline std::uint64_t mulx64(std::uint64_t x)noexcept
0090 {
0091   /* multiplier is 2^64/phi */
0092   std::uint64_t hi;
0093   std::uint64_t lo=umul128(x,0x9E3779B97F4A7C15ull,hi);
0094   return hi^lo;
0095 }
0096 
0097 } /* namespace detail */
0098 } /* namespace bloom */
0099 } /* namespace boost */
0100 #endif