Imported Upstream version 1.64.0
[platform/upstream/boost.git] / boost / multiprecision / detail / bitscan.hpp
index a21fd58..21e8b8a 100644 (file)
@@ -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)