forked from crashoz/uuid_v4
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathendianness.h
157 lines (143 loc) · 4.83 KB
/
endianness.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#pragma once
#if defined(__GLIBC__) || defined(__GNU_LIBRARY__) || defined(__ANDROID__)
#include <endian.h>
#elif defined(__APPLE__) && defined(__MACH__)
#include <machine/endian.h>
#elif defined(BSD) || defined(_SYSTYPE_BSD)
#if defined(__OpenBSD__)
#include <machine/endian.h>
#else
#include <sys/endian.h>
#endif
#endif
#if defined(__BYTE_ORDER)
#if defined(__BIG_ENDIAN) && (__BYTE_ORDER == __BIG_ENDIAN)
#define BIGENDIAN
#elif defined(__LITTLE_ENDIAN) && (__BYTE_ORDER == __LITTLE_ENDIAN)
#define LITTLEENDIAN
#endif
#elif defined(_BYTE_ORDER)
#if defined(_BIG_ENDIAN) && (_BYTE_ORDER == _BIG_ENDIAN)
#define BIGENDIAN
#elif defined(_LITTLE_ENDIAN) && (_BYTE_ORDER == _LITTLE_ENDIAN)
#define LITTLEENDIAN
#endif
#elif defined(__BIG_ENDIAN__)
#define BIGENDIAN
#elif defined(__LITTLE_ENDIAN__)
#define LITTLEENDIAN
#else
#if defined(__ARMEL__) || \
defined(__THUMBEL__) || \
defined(__AARCH64EL__) || \
defined(_MIPSEL) || \
defined(__MIPSEL) || \
defined(__MIPSEL__) || \
defined(__ia64__) || defined(_IA64) || \
defined(__IA64__) || defined(__ia64) || \
defined(_M_IA64) || defined(__itanium__) || \
defined(i386) || defined(__i386__) || \
defined(__i486__) || defined(__i586__) || \
defined(__i686__) || defined(__i386) || \
defined(_M_IX86) || defined(_X86_) || \
defined(__THW_INTEL__) || defined(__I86__) || \
defined(__INTEL__) || \
defined(__x86_64) || defined(__x86_64__) || \
defined(__amd64__) || defined(__amd64) || \
defined(_M_X64) || \
defined(__bfin__) || defined(__BFIN__) || \
defined(bfin) || defined(BFIN)
#define LITTLEENDIAN
#elif defined(__m68k__) || defined(M68000) || \
defined(__hppa__) || defined(__hppa) || defined(__HPPA__) || \
defined(__sparc__) || defined(__sparc) || \
defined(__370__) || defined(__THW_370__) || \
defined(__s390__) || defined(__s390x__) || \
defined(__SYSC_ZARCH__)
#define BIGENDIAN
#elif defined(__arm__) || defined(__arm64) || defined(__thumb__) || \
defined(__TARGET_ARCH_ARM) || defined(__TARGET_ARCH_THUMB) || \
defined(__ARM_ARCH) || \
defined(_M_ARM) || defined(_M_ARM64)
#if defined(_WIN32) || defined(_WIN64) || \
defined(__WIN32__) || defined(__TOS_WIN__) || \
defined(__WINDOWS__)
#define LITTLEENDIAN
#else
#error "Cannot determine system endianness."
#endif
#endif
#endif
#if defined(BIGENDIAN)
// Try to use compiler intrinsics
#if defined(__INTEL_COMPILER) || defined(__ICC)
#define betole16(x) _bswap16(x)
#define betole32(x) _bswap(x)
#define betole64(x) _bswap64(x)
#elif defined(__GNUC__) // GCC and CLANG
#define betole16(x) __builtin_bswap16(x)
#define betole32(x) __builtin_bswap32(x)
#define betole64(x) __builtin_bswap64(x)
#elif defined(_MSC_VER) // MSVC
#include <stdlib.h>
#define betole16(x) _byteswap_ushort(x)
#define betole32(x) _byteswap_ulong(x)
#define betole64(x) _byteswap_uint64(x)
#else
#define FALLBACK_SWAP
#define betole16(x) swap_u16(x)
#define betole32(x) swap_u32(x)
#define betole64(x) swap_u64(x)
#endif
#define betole128(x) swap_u128(x)
#define betole256(x) swap_u256(x)
#else
#define betole16(x) (x)
#define betole32(x) (x)
#define betole64(x) (x)
#define betole128(x) (x)
#define betole256(x) (x)
#endif // BIGENDIAN
#if defined(BIGENDIAN)
#include <emmintrin.h>
#include <smmintrin.h>
#include <immintrin.h>
#include <tmmintrin.h>
inline __m128i swap_u128(__m128i value) {
const __m128i shuffle = _mm_set_epi64x(0x0001020304050607, 0x08090a0b0c0d0e0f);
return _mm_shuffle_epi8(value, shuffle);
}
inline __m256i swap_u256(__m256i value) {
const __m256i shuffle = _mm256_set_epi64x(0x0001020304050607, 0x08090a0b0c0d0e0f, 0x0001020304050607, 0x08090a0b0c0d0e0f);
return _mm256_shuffle_epi8(value, shuffle);
}
#endif // BIGENDIAN
#if defined(FALLBACK_SWAP)
#include <stdint.h>
inline uint16_t swap_u16(uint16_t value)
{
return
((value & 0xFF00u) >> 8u) |
((value & 0x00FFu) << 8u);
}
inline uint32_t swap_u32(uint32_t value)
{
return
((value & 0xFF000000u) >> 24u) |
((value & 0x00FF0000u) >> 8u) |
((value & 0x0000FF00u) << 8u) |
((value & 0x000000FFu) << 24u);
}
inline uint64_t swap_u64(uint64_t value)
{
return
((value & 0xFF00000000000000u) >> 56u) |
((value & 0x00FF000000000000u) >> 40u) |
((value & 0x0000FF0000000000u) >> 24u) |
((value & 0x000000FF00000000u) >> 8u) |
((value & 0x00000000FF000000u) << 8u) |
((value & 0x0000000000FF0000u) << 24u) |
((value & 0x000000000000FF00u) << 40u) |
((value & 0x00000000000000FFu) << 56u);
}
#endif // FALLBACK_SWAP