endianness.h 2.2 KB

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