byteswap.h raw

   1  // Copyright (c) 2014-present The Bitcoin Core developers
   2  // Distributed under the MIT software license, see the accompanying
   3  // file COPYING or http://www.opensource.org/licenses/mit-license.php.
   4  
   5  #ifndef BITCOIN_COMPAT_BYTESWAP_H
   6  #define BITCOIN_COMPAT_BYTESWAP_H
   7  
   8  #include <cstdint>
   9  #ifdef _MSC_VER
  10  #include <cstdlib>
  11  #endif
  12  
  13  
  14  // All internal_bswap_* functions can be replaced with std::byteswap once we
  15  // require c++23. Both libstdc++ and libc++ implement std::byteswap via these
  16  // builtins.
  17  
  18  #ifndef DISABLE_BUILTIN_BSWAPS
  19  #  if defined __has_builtin
  20  #    if __has_builtin(__builtin_bswap16)
  21  #      define bitcoin_builtin_bswap16(x) __builtin_bswap16(x)
  22  #    endif
  23  #    if __has_builtin(__builtin_bswap32)
  24  #      define bitcoin_builtin_bswap32(x) __builtin_bswap32(x)
  25  #    endif
  26  #    if __has_builtin(__builtin_bswap64)
  27  #      define bitcoin_builtin_bswap64(x) __builtin_bswap64(x)
  28  #    endif
  29  #  elif defined(_MSC_VER)
  30  #      define bitcoin_builtin_bswap16(x) _byteswap_ushort(x)
  31  #      define bitcoin_builtin_bswap32(x) _byteswap_ulong(x)
  32  #      define bitcoin_builtin_bswap64(x) _byteswap_uint64(x)
  33  #  endif
  34  #endif
  35  
  36  // MSVC's _byteswap_* functions are not constexpr
  37  
  38  #ifndef _MSC_VER
  39  #define BSWAP_CONSTEXPR constexpr
  40  #else
  41  #define BSWAP_CONSTEXPR
  42  #endif
  43  
  44  inline BSWAP_CONSTEXPR uint16_t internal_bswap_16(uint16_t x)
  45  {
  46  #ifdef bitcoin_builtin_bswap16
  47      return bitcoin_builtin_bswap16(x);
  48  #else
  49      return (x >> 8) | (x << 8);
  50  #endif
  51  }
  52  
  53  inline BSWAP_CONSTEXPR uint32_t internal_bswap_32(uint32_t x)
  54  {
  55  #ifdef bitcoin_builtin_bswap32
  56      return bitcoin_builtin_bswap32(x);
  57  #else
  58      return (((x & 0xff000000U) >> 24) | ((x & 0x00ff0000U) >>  8) |
  59              ((x & 0x0000ff00U) <<  8) | ((x & 0x000000ffU) << 24));
  60  #endif
  61  }
  62  
  63  inline BSWAP_CONSTEXPR uint64_t internal_bswap_64(uint64_t x)
  64  {
  65  #ifdef bitcoin_builtin_bswap64
  66      return bitcoin_builtin_bswap64(x);
  67  #else
  68       return (((x & 0xff00000000000000ull) >> 56)
  69            | ((x & 0x00ff000000000000ull) >> 40)
  70            | ((x & 0x0000ff0000000000ull) >> 24)
  71            | ((x & 0x000000ff00000000ull) >> 8)
  72            | ((x & 0x00000000ff000000ull) << 8)
  73            | ((x & 0x0000000000ff0000ull) << 24)
  74            | ((x & 0x000000000000ff00ull) << 40)
  75            | ((x & 0x00000000000000ffull) << 56));
  76  #endif
  77  }
  78  
  79  #endif // BITCOIN_COMPAT_BYTESWAP_H
  80