summaryrefslogtreecommitdiffstats
path: root/contrib/libs/cxxsupp/libcxx/include/__bit/rotate.h
diff options
context:
space:
mode:
authormikhnenko <[email protected]>2025-04-19 17:15:47 +0300
committermikhnenko <[email protected]>2025-04-19 17:32:41 +0300
commit8a4ae1910b2babbc014f5d5ff97c2245803d6d1a (patch)
tree9c8728b4ad4226ef084d46a6d6cde7b5ae46e4d5 /contrib/libs/cxxsupp/libcxx/include/__bit/rotate.h
parent605a8a3075d2116bf0c742d7ae889ba14b801a8e (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.h37
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