brintos

brintos / llvm-project-archived public Read only

0
0
Text · 1.7 KiB · fbe121f Raw
58 lines · c
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef _LIBCPP___CXX03___BIT_ROTATE_H10#define _LIBCPP___CXX03___BIT_ROTATE_H11 12#include <__cxx03/__config>13#include <__cxx03/__type_traits/is_unsigned_integer.h>14#include <__cxx03/limits>15 16#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)17#  pragma GCC system_header18#endif19 20_LIBCPP_BEGIN_NAMESPACE_STD21 22// Writing two full functions for rotl and rotr makes it easier for the compiler23// to optimize the code. On x86 this function becomes the ROL instruction and24// the rotr function becomes the ROR instruction.25template <class _Tp>26_LIBCPP_HIDE_FROM_ABI _Tp __rotl(_Tp __x, int __s) _NOEXCEPT {27  static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__rotl requires an unsigned integer type");28  const int __N = numeric_limits<_Tp>::digits;29  int __r       = __s % __N;30 31  if (__r == 0)32    return __x;33 34  if (__r > 0)35    return (__x << __r) | (__x >> (__N - __r));36 37  return (__x >> -__r) | (__x << (__N + __r));38}39 40template <class _Tp>41_LIBCPP_HIDE_FROM_ABI _Tp __rotr(_Tp __x, int __s) _NOEXCEPT {42  static_assert(__libcpp_is_unsigned_integer<_Tp>::value, "__rotr requires an unsigned integer type");43  const int __N = numeric_limits<_Tp>::digits;44  int __r       = __s % __N;45 46  if (__r == 0)47    return __x;48 49  if (__r > 0)50    return (__x >> __r) | (__x << (__N - __r));51 52  return (__x << -__r) | (__x >> (__N + __r));53}54 55_LIBCPP_END_NAMESPACE_STD56 57#endif // _LIBCPP___CXX03___BIT_ROTATE_H58