diff options
| author | mikhnenko <[email protected]> | 2025-04-19 17:15:47 +0300 |
|---|---|---|
| committer | mikhnenko <[email protected]> | 2025-04-19 17:32:41 +0300 |
| commit | 8a4ae1910b2babbc014f5d5ff97c2245803d6d1a (patch) | |
| tree | 9c8728b4ad4226ef084d46a6d6cde7b5ae46e4d5 /contrib/libs/cxxsupp/libcxx/include/__bit/rotate.h | |
| parent | 605a8a3075d2116bf0c742d7ae889ba14b801a8e (diff) | |
Update libcxx to 20 Sep 2024
TRIVIAL
commit_hash:04d8ae0a53854a1ed8cdea2e191c8dfa1248c023
Diffstat (limited to 'contrib/libs/cxxsupp/libcxx/include/__bit/rotate.h')
| -rw-r--r-- | contrib/libs/cxxsupp/libcxx/include/__bit/rotate.h | 37 |
1 files changed, 25 insertions, 12 deletions
diff --git a/contrib/libs/cxxsupp/libcxx/include/__bit/rotate.h b/contrib/libs/cxxsupp/libcxx/include/__bit/rotate.h index d848056c335..d79d98de296 100644 --- a/contrib/libs/cxxsupp/libcxx/include/__bit/rotate.h +++ b/contrib/libs/cxxsupp/libcxx/include/__bit/rotate.h @@ -20,24 +20,37 @@ _LIBCPP_BEGIN_NAMESPACE_STD +// Writing two full functions for rotl and rotr makes it easier for the compiler +// to optimize the code. On x86 this function becomes the ROL instruction and +// the rotr function becomes the ROR instruction. template <class _Tp> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp __rotr(_Tp __t, int __cnt) _NOEXCEPT { - static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__rotr requires an unsigned integer type"); - const unsigned int __dig = numeric_limits<_Tp>::digits; - if ((__cnt % __dig) == 0) - return __t; +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp __rotl(_Tp __x, int __s) _NOEXCEPT { + static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__rotl requires an unsigned integer type"); + const int __n = numeric_limits<_Tp>::digits; + int __r = __s % __n; + + if (__r == 0) + return __x; - if (__cnt < 0) { - __cnt *= -1; - return (__t << (__cnt % __dig)) | (__t >> (__dig - (__cnt % __dig))); // rotr with negative __cnt is similar to rotl - } + if (__r > 0) + return (__x << __r) | (__x >> (__n - __r)); - return (__t >> (__cnt % __dig)) | (__t << (__dig - (__cnt % __dig))); + return (__x >> -__r) | (__x << (__n + __r)); } template <class _Tp> -_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp __rotl(_Tp __t, int __cnt) _NOEXCEPT { - return std::__rotr(__t, -__cnt); +_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp __rotr(_Tp __x, int __s) _NOEXCEPT { + static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__rotr requires an unsigned integer type"); + const int __n = numeric_limits<_Tp>::digits; + int __r = __s % __n; + + if (__r == 0) + return __x; + + if (__r > 0) + return (__x >> __r) | (__x << (__n - __r)); + + return (__x << -__r) | (__x >> (__n + __r)); } #if _LIBCPP_STD_VER >= 20 |
