diff --git a/Utilities/BEType.h b/Utilities/BEType.h index 79dde382aa..67918fcf16 100644 --- a/Utilities/BEType.h +++ b/Utilities/BEType.h @@ -4,6 +4,12 @@ #include "util/endian.hpp" #include +#if __has_include() +#include +#else +#include +#endif + // 128-bit vector type and also se_storage<> storage type union alignas(16) v128 { @@ -26,12 +32,10 @@ union alignas(16) v128 } }; -#if IS_LE_MACHINE == 1 template - using normal_array_t = masked_array_t; + using normal_array_t = masked_array_t; template - using reversed_array_t = masked_array_t; -#endif + using reversed_array_t = masked_array_t; normal_array_t _u64; normal_array_t _s64; @@ -114,17 +118,27 @@ union alignas(16) v128 // Index 0 returns the MSB and index 127 returns the LSB bit_element operator[](u32 index) { -#if IS_LE_MACHINE == 1 - return bit_element(m_data[1 - (index >> 6)], 0x8000000000000000ull >> (index & 0x3F)); -#endif + if constexpr (std::endian::little == std::endian::native) + { + return bit_element(m_data[1 - (index >> 6)], 0x8000000000000000ull >> (index & 0x3F)); + } + else + { + return bit_element(m_data[index >> 6], 0x8000000000000000ull >> (index & 0x3F)); + } } // Index 0 returns the MSB and index 127 returns the LSB bool operator[](u32 index) const { -#if IS_LE_MACHINE == 1 - return (m_data[1 - (index >> 6)] & (0x8000000000000000ull >> (index & 0x3F))) != 0; -#endif + if constexpr (std::endian::little == std::endian::native) + { + return (m_data[1 - (index >> 6)] & (0x8000000000000000ull >> (index & 0x3F))) != 0; + } + else + { + return (m_data[index >> 6] & (0x8000000000000000ull >> (index & 0x3F))) != 0; + } } } _bit; @@ -340,12 +354,10 @@ using stx::se_storage; template using nse_t = se_t; -#if IS_LE_MACHINE == 1 template -using be_t = se_t; +using be_t = se_t; template -using le_t = se_t; -#endif +using le_t = se_t; // Type converter: converts native endianness arithmetic/enum types to appropriate se_t<> type template @@ -414,20 +426,16 @@ struct to_se }; // BE/LE aliases for to_se<> -#if IS_LE_MACHINE == 1 template -using to_be_t = typename to_se::type; +using to_be_t = typename to_se::type; template -using to_le_t = typename to_se::type; -#endif +using to_le_t = typename to_se::type; // BE/LE aliases for atomic_t -#if IS_LE_MACHINE == 1 template using atomic_be_t = atomic_t>; template using atomic_le_t = atomic_t>; -#endif template struct fmt_unveil, void> diff --git a/Utilities/types.h b/Utilities/types.h index 69a441482c..d076db6df1 100644 --- a/Utilities/types.h +++ b/Utilities/types.h @@ -17,9 +17,9 @@ #include #include -// Assume little-endian -#define IS_LE_MACHINE 1 -#define IS_BE_MACHINE 0 +#if __has_include() +#include +#endif #ifndef __has_builtin #define __has_builtin(x) 0 @@ -82,7 +82,7 @@ #define AUDIT(...) ((void)0) #endif -#if defined(__cpp_lib_bit_cast) && (__cpp_lib_bit_cast >= 201806L) +#if __cpp_lib_bit_cast >= 201806L #include #else namespace std @@ -530,31 +530,56 @@ constexpr u32 to_u8(char c) return static_cast(c); } -// Convert 2-byte string to u16 value like reinterpret_cast does +// Convert 1-2-byte string to u16 value like reinterpret_cast does constexpr u16 operator""_u16(const char* s, std::size_t /*length*/) { - return -#if IS_LE_MACHINE == 1 - static_cast(to_u8(s[1]) << 8 | to_u8(s[0])); -#endif + if constexpr (std::endian::little == std::endian::native) + { + return static_cast(to_u8(s[1]) << 8 | to_u8(s[0])); + } + else + { + return static_cast(to_u8(s[0]) << 8 | to_u8(s[1])); + } } -// Convert 4-byte string to u32 value like reinterpret_cast does +// Convert 3-4-byte string to u32 value like reinterpret_cast does constexpr u32 operator""_u32(const char* s, std::size_t /*length*/) { - return -#if IS_LE_MACHINE == 1 - to_u8(s[3]) << 24 | to_u8(s[2]) << 16 | to_u8(s[1]) << 8 | to_u8(s[0]); -#endif + if constexpr (std::endian::little == std::endian::native) + { + return to_u8(s[3]) << 24 | to_u8(s[2]) << 16 | to_u8(s[1]) << 8 | to_u8(s[0]); + } + else + { + return to_u8(s[0]) << 24 | to_u8(s[1]) << 16 | to_u8(s[2]) << 8 | to_u8(s[3]); + } } -// Convert 8-byte string to u64 value like reinterpret_cast does +// Convert 5-6-byte string to u64 value like reinterpret_cast does +constexpr u64 operator""_u48(const char* s, std::size_t /*length*/) +{ + if constexpr (std::endian::little == std::endian::native) + { + return static_cast(to_u8(s[5]) << 8 | to_u8(s[4])) << 32 | to_u8(s[3]) << 24 | to_u8(s[2]) << 16 | to_u8(s[1]) << 8 | to_u8(s[0]); + } + else + { + return static_cast(to_u8(s[0]) << 8 | to_u8(s[1])) << 32 | to_u8(s[2]) << 24 | to_u8(s[3]) << 16 | to_u8(s[4]) << 8 | to_u8(s[5]); + } +} + +// Convert 7-8-byte string to u64 value like reinterpret_cast does constexpr u64 operator""_u64(const char* s, std::size_t /*length*/) { - return -#if IS_LE_MACHINE == 1 - static_cast(to_u8(s[7]) << 24 | to_u8(s[6]) << 16 | to_u8(s[5]) << 8 | to_u8(s[4])) << 32 | to_u8(s[3]) << 24 | to_u8(s[2]) << 16 | to_u8(s[1]) << 8 | to_u8(s[0]); -#endif + if constexpr (std::endian::little == std::endian::native) + { + return static_cast(to_u8(s[7]) << 24 | to_u8(s[6]) << 16 | to_u8(s[5]) << 8 | to_u8(s[4])) << 32 | to_u8(s[3]) << 24 | to_u8(s[2]) << 16 | to_u8(s[1]) << 8 | to_u8(s[0]); + } + else + { + return static_cast(to_u8(s[0]) << 24 | to_u8(s[1]) << 16 | to_u8(s[2]) << 8 | to_u8(s[3])) << 32 | to_u8(s[4]) << 24 | to_u8(s[5]) << 16 | to_u8(s[6]) << 8 | to_u8(s[7]); + } } namespace fmt diff --git a/rpcs3/util/endian.hpp b/rpcs3/util/endian.hpp index 6be788ad77..9a95727ad1 100644 --- a/rpcs3/util/endian.hpp +++ b/rpcs3/util/endian.hpp @@ -3,8 +3,16 @@ #include #include "Utilities/types.h" +#if __has_include() +#include +#else +#include +#endif + namespace stx { + static_assert(std::endian::native == std::endian::little || std::endian::native == std::endian::big); + template struct se_storage {