/ src / compat / byteswap.h
byteswap.h
 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