diff options
Diffstat (limited to 'src/common/swap.h')
| -rw-r--r-- | src/common/swap.h | 96 |
1 files changed, 27 insertions, 69 deletions
diff --git a/src/common/swap.h b/src/common/swap.h index b3eab1324..71932c2bb 100644 --- a/src/common/swap.h +++ b/src/common/swap.h | |||
| @@ -21,11 +21,6 @@ | |||
| 21 | 21 | ||
| 22 | #if defined(_MSC_VER) | 22 | #if defined(_MSC_VER) |
| 23 | #include <cstdlib> | 23 | #include <cstdlib> |
| 24 | #elif defined(__linux__) | ||
| 25 | #include <byteswap.h> | ||
| 26 | #elif defined(__Bitrig__) || defined(__DragonFly__) || defined(__FreeBSD__) || \ | ||
| 27 | defined(__NetBSD__) || defined(__OpenBSD__) | ||
| 28 | #include <sys/endian.h> | ||
| 29 | #endif | 24 | #endif |
| 30 | #include <cstring> | 25 | #include <cstring> |
| 31 | #include "common/common_types.h" | 26 | #include "common/common_types.h" |
| @@ -62,86 +57,49 @@ | |||
| 62 | namespace Common { | 57 | namespace Common { |
| 63 | 58 | ||
| 64 | #ifdef _MSC_VER | 59 | #ifdef _MSC_VER |
| 65 | inline u16 swap16(u16 _data) { | 60 | [[nodiscard]] inline u16 swap16(u16 data) noexcept { |
| 66 | return _byteswap_ushort(_data); | 61 | return _byteswap_ushort(data); |
| 67 | } | 62 | } |
| 68 | inline u32 swap32(u32 _data) { | 63 | [[nodiscard]] inline u32 swap32(u32 data) noexcept { |
| 69 | return _byteswap_ulong(_data); | 64 | return _byteswap_ulong(data); |
| 70 | } | 65 | } |
| 71 | inline u64 swap64(u64 _data) { | 66 | [[nodiscard]] inline u64 swap64(u64 data) noexcept { |
| 72 | return _byteswap_uint64(_data); | 67 | return _byteswap_uint64(data); |
| 73 | } | 68 | } |
| 74 | #elif defined(ARCHITECTURE_ARM) && (__ARM_ARCH >= 6) | 69 | #elif defined(__clang__) || defined(__GNUC__) |
| 75 | inline u16 swap16(u16 _data) { | 70 | #if defined(__Bitrig__) || defined(__OpenBSD__) |
| 76 | u32 data = _data; | ||
| 77 | __asm__("rev16 %0, %1\n" : "=l"(data) : "l"(data)); | ||
| 78 | return (u16)data; | ||
| 79 | } | ||
| 80 | inline u32 swap32(u32 _data) { | ||
| 81 | __asm__("rev %0, %1\n" : "=l"(_data) : "l"(_data)); | ||
| 82 | return _data; | ||
| 83 | } | ||
| 84 | inline u64 swap64(u64 _data) { | ||
| 85 | return ((u64)swap32(_data) << 32) | swap32(_data >> 32); | ||
| 86 | } | ||
| 87 | #elif __linux__ | ||
| 88 | inline u16 swap16(u16 _data) { | ||
| 89 | return bswap_16(_data); | ||
| 90 | } | ||
| 91 | inline u32 swap32(u32 _data) { | ||
| 92 | return bswap_32(_data); | ||
| 93 | } | ||
| 94 | inline u64 swap64(u64 _data) { | ||
| 95 | return bswap_64(_data); | ||
| 96 | } | ||
| 97 | #elif __APPLE__ | ||
| 98 | inline __attribute__((always_inline)) u16 swap16(u16 _data) { | ||
| 99 | return (_data >> 8) | (_data << 8); | ||
| 100 | } | ||
| 101 | inline __attribute__((always_inline)) u32 swap32(u32 _data) { | ||
| 102 | return __builtin_bswap32(_data); | ||
| 103 | } | ||
| 104 | inline __attribute__((always_inline)) u64 swap64(u64 _data) { | ||
| 105 | return __builtin_bswap64(_data); | ||
| 106 | } | ||
| 107 | #elif defined(__Bitrig__) || defined(__OpenBSD__) | ||
| 108 | // redefine swap16, swap32, swap64 as inline functions | 71 | // redefine swap16, swap32, swap64 as inline functions |
| 109 | #undef swap16 | 72 | #undef swap16 |
| 110 | #undef swap32 | 73 | #undef swap32 |
| 111 | #undef swap64 | 74 | #undef swap64 |
| 112 | inline u16 swap16(u16 _data) { | 75 | #endif |
| 113 | return __swap16(_data); | 76 | [[nodiscard]] inline u16 swap16(u16 data) noexcept { |
| 114 | } | 77 | return __builtin_bswap16(data); |
| 115 | inline u32 swap32(u32 _data) { | ||
| 116 | return __swap32(_data); | ||
| 117 | } | ||
| 118 | inline u64 swap64(u64 _data) { | ||
| 119 | return __swap64(_data); | ||
| 120 | } | ||
| 121 | #elif defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) | ||
| 122 | inline u16 swap16(u16 _data) { | ||
| 123 | return bswap16(_data); | ||
| 124 | } | 78 | } |
| 125 | inline u32 swap32(u32 _data) { | 79 | [[nodiscard]] inline u32 swap32(u32 data) noexcept { |
| 126 | return bswap32(_data); | 80 | return __builtin_bswap32(data); |
| 127 | } | 81 | } |
| 128 | inline u64 swap64(u64 _data) { | 82 | [[nodiscard]] inline u64 swap64(u64 data) noexcept { |
| 129 | return bswap64(_data); | 83 | return __builtin_bswap64(data); |
| 130 | } | 84 | } |
| 131 | #else | 85 | #else |
| 132 | // Slow generic implementation. | 86 | // Generic implementation. |
| 133 | inline u16 swap16(u16 data) { | 87 | [[nodiscard]] inline u16 swap16(u16 data) noexcept { |
| 134 | return (data >> 8) | (data << 8); | 88 | return (data >> 8) | (data << 8); |
| 135 | } | 89 | } |
| 136 | inline u32 swap32(u32 data) { | 90 | [[nodiscard]] inline u32 swap32(u32 data) noexcept { |
| 137 | return (swap16(data) << 16) | swap16(data >> 16); | 91 | return ((data & 0xFF000000U) >> 24) | ((data & 0x00FF0000U) >> 8) | |
| 92 | ((data & 0x0000FF00U) << 8) | ((data & 0x000000FFU) << 24); | ||
| 138 | } | 93 | } |
| 139 | inline u64 swap64(u64 data) { | 94 | [[nodiscard]] inline u64 swap64(u64 data) noexcept { |
| 140 | return ((u64)swap32(data) << 32) | swap32(data >> 32); | 95 | return ((data & 0xFF00000000000000ULL) >> 56) | ((data & 0x00FF000000000000ULL) >> 40) | |
| 96 | ((data & 0x0000FF0000000000ULL) >> 24) | ((data & 0x000000FF00000000ULL) >> 8) | | ||
| 97 | ((data & 0x00000000FF000000ULL) << 8) | ((data & 0x0000000000FF0000ULL) << 24) | | ||
| 98 | ((data & 0x000000000000FF00ULL) << 40) | ((data & 0x00000000000000FFULL) << 56); | ||
| 141 | } | 99 | } |
| 142 | #endif | 100 | #endif |
| 143 | 101 | ||
| 144 | inline float swapf(float f) { | 102 | [[nodiscard]] inline float swapf(float f) noexcept { |
| 145 | static_assert(sizeof(u32) == sizeof(float), "float must be the same size as uint32_t."); | 103 | static_assert(sizeof(u32) == sizeof(float), "float must be the same size as uint32_t."); |
| 146 | 104 | ||
| 147 | u32 value; | 105 | u32 value; |
| @@ -153,7 +111,7 @@ inline float swapf(float f) { | |||
| 153 | return f; | 111 | return f; |
| 154 | } | 112 | } |
| 155 | 113 | ||
| 156 | inline double swapd(double f) { | 114 | [[nodiscard]] inline double swapd(double f) noexcept { |
| 157 | static_assert(sizeof(u64) == sizeof(double), "double must be the same size as uint64_t."); | 115 | static_assert(sizeof(u64) == sizeof(double), "double must be the same size as uint64_t."); |
| 158 | 116 | ||
| 159 | u64 value; | 117 | u64 value; |