xref: /PHP-8.3/ext/hash/murmur/endianness.h (revision 12dc5197)
1 static const union {
2   uint8_t u8[2];
3   uint16_t u16;
4 } EndianMix = {{ 1, 0 }};
IsBigEndian(void)5 FORCE_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)36 FORCE_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)45 FORCE_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)65 FORCE_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)75 FORCE_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