SPARK  0.1.0
A general purpose game engine written in C++.
Loading...
Searching...
No Matches
Endianness.h
1#pragma once
2
3#pragma once
4
5#if defined(__GLIBC__) || defined(__GNU_LIBRARY__) || defined(__ANDROID__)
6# include <endian.h>
7#elif defined(__APPLE__) && defined(__MACH__)
8# include <machine/endian.h>
9#elif defined(BSD) || defined(_SYSTYPE_BSD)
10# if defined(__OpenBSD__)
11# include <machine/endian.h>
12# else
13# include <sys/endian.h>
14# endif
15#endif
16
17#if defined(__BYTE_ORDER)
18# if defined(__BIG_ENDIAN) && (__BYTE_ORDER == __BIG_ENDIAN)
19# define BIG_ENDIAN
20# elif defined(__LITTLE_ENDIAN) && (__BYTE_ORDER == __LITTLE_ENDIAN) && !defined(LITTLE_ENDIAN)
21# define LITTLE_ENDIAN
22# endif
23# elif defined(_BYTE_ORDER)
24# if defined(_BIG_ENDIAN) && (_BYTE_ORDER == _BIG_ENDIAN)
25# define BIG_ENDIAN
26# elif defined(_LITTLE_ENDIAN) && (_BYTE_ORDER == _LITTLE_ENDIAN)
27# define LITTLE_ENDIAN
28# endif
29# elif defined(__BIG_ENDIAN__)
30# define BIG_ENDIAN
31# elif defined(__LITTLE_ENDIAN__)
32# define LITTLE_ENDIAN
33#else
34# if defined(__ARMEL__) || defined(__THUMBEL__) || defined(__AARCH64EL__) || defined(_MIPSEL) || defined(__MIPSEL) || defined(__MIPSEL__) || defined(__ia64__) || defined(_IA64) || \
35 defined(__IA64__) || defined(__ia64) || defined(_M_IA64) || defined(__itanium__) || defined(i386) || defined(__i386__) || defined(__i486__) || defined(__i586__) || \
36 defined(__i686__) || defined(__i386) || defined(_M_IX86) || defined(_X86_) || defined(__THW_INTEL__) || defined(__I86__) || defined(__INTEL__) || defined(__x86_64) || \
37 defined(__x86_64__) || defined(__amd64__) || defined(__amd64) || defined(_M_X64) || defined(__bfin__) || defined(__BFIN__) || defined(bfin) || defined(BFIN)
38# define LITTLE_ENDIAN
39# elif defined(__m68k__) || defined(M68000) || defined(__hppa__) || defined(__hppa) || defined(__HPPA__) || defined(__sparc__) || defined(__sparc) || defined(__370__) || \
40 defined(__THW_370__) || defined(__s390__) || defined(__s390x__) || defined(__SYSC_ZARCH__)
41# define BIG_ENDIAN
42# elif defined(__arm__) || defined(__arm64) || defined(__thumb__) || defined(__TARGET_ARCH_ARM) || defined(__TARGET_ARCH_THUMB) || defined(__ARM_ARCH) || defined(_M_ARM) || defined(_M_ARM64)
43# if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(__TOS_WIN__) || defined(__WINDOWS__)
44# define LITTLE_ENDIAN
45# else
46# error "Cannot determine system endianness."
47# endif
48# endif
49#endif
50
51#if defined(BIG_ENDIAN)
52// Try to use compiler intrinsics
53#if defined(__INTEL_COMPILER) || defined(__ICC)
54# define betole16(x) _bswap16(x)
55# define betole32(x) _bswap(x)
56# define betole64(x) _bswap64(x)
57#elif defined(__GNUC__) // GCC and CLANG
58# define betole16(x) __builtin_bswap16(x)
59# define betole32(x) __builtin_bswap32(x)
60# define betole64(x) __builtin_bswap64(x)
61#elif defined(_MSC_VER) // MSVC
62# include <cstdlib>
63# define betole16(x) _byteswap_ushort(x)
64# define betole32(x) _byteswap_ulong(x)
65# define betole64(x) _byteswap_uint64(x)
66#else
67# define FALLBACK_SWAP
68# define betole16(x) swap_u16(x)
69# define betole32(x) swap_u32(x)
70# define betole64(x) swap_u64(x)
71#endif
72# define betole128(x) swap_u128(x)
73# define betole256(x) swap_u256(x)
74#else
75# define betole16(x) (x)
76# define betole32(x) (x)
77# define betole64(x) (x)
78# define betole128(x) (x)
79# define betole256(x) (x)
80#endif
81
82#if defined(BIG_ENDIAN)
83# include <emmintrin.h>
84# include <immintrin.h>
85# include <smmintrin.h>
86# include <tmmintrin.h>
87
88 inline __m128i swap_u128(__m128i value)
89 {
90 const __m128i shuffle = _mm_set_epi64x(0x0001020304050607, 0x08090a0b0c0d0e0f);
91 return _mm_shuffle_epi8(value, shuffle);
92 }
93
94 inline __m256i swap_u256(__m256i value)
95 {
96 const __m256i shuffle = _mm256_set_epi64x(0x0001020304050607, 0x08090a0b0c0d0e0f, 0x0001020304050607, 0x08090a0b0c0d0e0f);
97 return _mm256_shuffle_epi8(value, shuffle);
98 }
99#else
100# include <emmintrin.h>
101# include <immintrin.h>
102# include <smmintrin.h>
103# include <tmmintrin.h>
104#endif
105
106#if defined(FALLBACK_SWAP)
107# include <cstdint>
108 inline uint16_t swap_u16(uint16_t value)
109 {
110 return ((value & 0xFF00u) >> 8u) | ((value & 0x00FFu) << 8u);
111 }
112 inline uint32_t swap_u32(uint32_t value)
113 {
114 return ((value & 0xFF000000u) >> 24u) | ((value & 0x00FF0000u) >> 8u) | ((value & 0x0000FF00u) << 8u) | ((value & 0x000000FFu) << 24u);
115 }
116 inline uint64_t swap_u64(uint64_t value)
117 {
118 return ((value & 0xFF00000000000000u) >> 56u) | ((value & 0x00FF000000000000u) >> 40u) | ((value & 0x0000FF0000000000u) >> 24u) | ((value & 0x000000FF00000000u) >> 8u) |
119 ((value & 0x00000000FF000000u) << 8u) | ((value & 0x0000000000FF0000u) << 24u) | ((value & 0x000000000000FF00u) << 40u) | ((value & 0x00000000000000FFu) << 56u);
120 }
121#endif