1 static const union { 2 uint8_t u8[2]; 3 uint16_t u16; 4 } EndianMix = {{ 1, 0 }}; IsBigEndian(void)5FORCE_INLINE int IsBigEndian(void) 6 { 7 // Constant-folded by the compiler. 8 return EndianMix.u16 != 1; 9 } 10 11 #if defined(_MSC_VER) 12 # include <stdlib.h> 13 # define BSWAP32(u) _byteswap_ulong(u) 14 # define BSWAP64(u) _byteswap_uint64(u) 15 #else 16 # if defined(__GNUC__) && ( \ 17 __GNUC__ > 4 || ( \ 18 __GNUC__ == 4 && ( \ 19 __GNUC_MINOR__ >= 3 \ 20 ) \ 21 ) \ 22 ) 23 # define BSWAP32(u) __builtin_bswap32(u) 24 # define BSWAP64(u) __builtin_bswap64(u) 25 # elif defined(__has_builtin) 26 # if __has_builtin(__builtin_bswap32) 27 # define BSWAP32(u) __builtin_bswap32(u) 28 # endif // __has_builtin(__builtin_bswap32) 29 # if __has_builtin(__builtin_bswap64) 30 # define BSWAP64(u) __builtin_bswap64(u) 31 # endif // __has_builtin(__builtin_bswap64) 32 # endif // __has_builtin 33 #endif // defined(_MSC_VER) 34 35 #ifndef BSWAP32 BSWAP32(uint32_t u)36FORCE_INLINE uint32_t BSWAP32(uint32_t u) 37 { 38 return (((u & 0xff000000) >> 24) 39 | ((u & 0x00ff0000) >> 8) 40 | ((u & 0x0000ff00) << 8) 41 | ((u & 0x000000ff) << 24)); 42 } 43 #endif 44 #ifndef BSWAP64 BSWAP64(uint64_t u)45FORCE_INLINE uint64_t BSWAP64(uint64_t u) 46 { 47 return (((u & 0xff00000000000000ULL) >> 56) 48 | ((u & 0x00ff000000000000ULL) >> 40) 49 | ((u & 0x0000ff0000000000ULL) >> 24) 50 | ((u & 0x000000ff00000000ULL) >> 8) 51 | ((u & 0x00000000ff000000ULL) << 8) 52 | ((u & 0x0000000000ff0000ULL) << 24) 53 | ((u & 0x000000000000ff00ULL) << 40) 54 | ((u & 0x00000000000000ffULL) << 56)); 55 } 56 #endif 57 58 #if defined(__clang__) || defined(__GNUC__) && __GNUC__ >= 8 59 # define NO_SANITIZE_ALIGNMENT __attribute__((no_sanitize("alignment"))) 60 #else 61 # define NO_SANITIZE_ALIGNMENT 62 #endif 63 64 NO_SANITIZE_ALIGNMENT getblock32(const uint32_t * const p,const int i)65FORCE_INLINE uint32_t getblock32 ( const uint32_t * const p, const int i) 66 { 67 if (IsBigEndian()) { 68 return BSWAP32(p[i]); 69 } else { 70 return p[i]; 71 } 72 } 73 74 NO_SANITIZE_ALIGNMENT getblock64(const uint64_t * const p,const int i)75FORCE_INLINE uint64_t getblock64 ( const uint64_t * const p, const int i) 76 { 77 if (IsBigEndian()) { 78 return BSWAP64(p[i]); 79 } else { 80 return p[i]; 81 } 82 } 83 84 #undef NO_SANITIZE_ALIGNMENT 85