diff options
Diffstat (limited to 'boost/multiprecision/detail/bitscan.hpp')
-rw-r--r-- | boost/multiprecision/detail/bitscan.hpp | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/boost/multiprecision/detail/bitscan.hpp b/boost/multiprecision/detail/bitscan.hpp index a21fd58651..21e8b8a3a9 100644 --- a/boost/multiprecision/detail/bitscan.hpp +++ b/boost/multiprecision/detail/bitscan.hpp @@ -8,6 +8,8 @@ #ifndef BOOST_MP_DETAIL_BITSCAN_HPP #define BOOST_MP_DETAIL_BITSCAN_HPP +#include <boost/detail/endian.hpp> + #if (defined(BOOST_MSVC) || (defined(__clang__) && defined(__c2__)) || (defined(BOOST_INTEL) && defined(_MSC_VER))) && (defined(_M_IX86) || defined(_M_X64)) #include <intrin.h> #endif @@ -140,6 +142,36 @@ BOOST_FORCEINLINE unsigned find_msb(boost::ulong_long_type mask, mpl::int_<3> co { return sizeof(boost::ulong_long_type) * CHAR_BIT - 1 - __builtin_clzll(mask); } +#ifdef BOOST_HAS_INT128 +BOOST_FORCEINLINE unsigned find_msb(unsigned __int128 mask, mpl::int_<0> const&) +{ + union { unsigned __int128 v; boost::uint64_t sv[2]; } val; + val.v = mask; +#ifdef BOOST_LITTLE_ENDIAN + if(val.sv[1]) + return find_msb(val.sv[1], mpl::int_<3>()) + 64; + return find_msb(val.sv[0], mpl::int_<3>()); +#else + if(val.sv[0]) + return find_msb(val.sv[0], mpl::int_<3>()) + 64; + return find_msb(val.sv[1], mpl::int_<3>()); +#endif +} +BOOST_FORCEINLINE unsigned find_lsb(unsigned __int128 mask, mpl::int_<0> const&) +{ + union { unsigned __int128 v; boost::uint64_t sv[2]; } val; + val.v = mask; +#ifdef BOOST_LITTLE_ENDIAN + if(val.sv[0] == 0) + return find_lsb(val.sv[1], mpl::int_<3>()) + 64; + return find_lsb(val.sv[0], mpl::int_<3>()); +#else + if(val.sv[1] == 0) + return find_lsb(val.sv[0], mpl::int_<3>()) + 64; + return find_lsb(val.sv[1], mpl::int_<3>()); +#endif +} +#endif template <class Unsigned> BOOST_FORCEINLINE unsigned find_lsb(Unsigned mask) |