feature: add endianness handling and byte swap macros for cross-platform compatibility
This commit is contained in:
parent
f3d307c03e
commit
0db765dc98
1 changed files with 139 additions and 0 deletions
139
Source/DrangPlatform/Include/drang/endianness.h
Normal file
139
Source/DrangPlatform/Include/drang/endianness.h
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
#pragma once
|
||||
#include "platform.h"
|
||||
#include <stdint.h>
|
||||
#if !defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__)
|
||||
# ifdef __has_include
|
||||
# if __has_include(<endian.h>)
|
||||
# include <endian.h> // gnu libc normally provides, linux
|
||||
# elif __has_include(<machine/endian.h>)
|
||||
# include <machine/endian.h> //open bsd, macos
|
||||
# elif __has_include(<sys/param.h>)
|
||||
# include <sys/param.h> // mingw, some bsd (not open/macos)
|
||||
# elif __has_include(<sys/isadefs.h>)
|
||||
# include <sys/isadefs.h> // solaris
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__)
|
||||
# if (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) \
|
||||
|| (defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN) \
|
||||
|| (defined(_BYTE_ORDER) && _BYTE_ORDER == _BIG_ENDIAN) || (defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN) \
|
||||
|| (defined(__sun) && defined(__SVR4) && defined(_BIG_ENDIAN)) || defined(__ARMEB__) || defined(__THUMBEB__) \
|
||||
|| defined(__AARCH64EB__) || defined(_MIBSEB) || defined(__MIBSEB) || defined(__MIBSEB__) || defined(_M_PPC)
|
||||
# define __BIG_ENDIAN__
|
||||
# elif (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || /* gcc */ \
|
||||
(defined(__BYTE_ORDER) && __BYTE_ORDER == __LITTLE_ENDIAN) /* linux header */ \
|
||||
|| (defined(_BYTE_ORDER) && _BYTE_ORDER == _LITTLE_ENDIAN) \
|
||||
|| (defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN) /* mingw header */ \
|
||||
|| (defined(__sun) && defined(__SVR4) && defined(_LITTLE_ENDIAN)) || /* solaris */ \
|
||||
defined(__ARMEL__) || defined(__THUMBEL__) || defined(__AARCH64EL__) || defined(_MIPSEL) || defined(__MIPSEL) \
|
||||
|| defined(__MIPSEL__) || defined(_M_IX86) || defined(_M_X64) || defined(_M_IA64) \
|
||||
|| /* msvc for intel processors */ \
|
||||
defined(_M_ARM) /* msvc code on arm executes in little endian mode */
|
||||
# define __LITTLE_ENDIAN__
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if !defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__)
|
||||
# error "Unknown endianness"
|
||||
#endif
|
||||
|
||||
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) || defined(__clang__)
|
||||
# define DRANG_BSWAP8(_X_) (_X_)
|
||||
# define DRANG_BSWAP16(_X_) (__builtin_bswap16(_X_))
|
||||
# define DRANG_BSWAP32(_X_) (__builtin_bswap32(_X_))
|
||||
# define DRANG_BSWAP64(_X_) (__builtin_bswap64(_X_))
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
# include <stdlib.h>
|
||||
# define DRANG_BSWAP8(_X_) (_X_)
|
||||
# define DRANG_BSWAP16(_X_) (_byteswap_ushort(_X_))
|
||||
# define DRANG_BSWAP32(_X_) (_byteswap_ulong(_X_))
|
||||
# define DRANG_BSWAP64(_X_) (_byteswap_uint64(_X_))
|
||||
#else
|
||||
static inline uint16 drang_bswap16_impl(const uint16_t x)
|
||||
{
|
||||
return (((x >> 8) & 0xFFu) | ((x & 0xFFu) << 8));
|
||||
}
|
||||
static inline uint32_t drang_bswap32_impl(const uint32_t x)
|
||||
{
|
||||
return (((x & 0xFF000000u) >> 24) | ((x & 0x00FF0000u) >> 8) | ((x & 0x0000FF00u) << 8) | ((x & 0x000000FFu) << 24));
|
||||
}
|
||||
|
||||
static inline uint64_t drang_bswap64_impl(const uint64_t x)
|
||||
{
|
||||
return (((x & 0xFF00000000000000ull) >> 56) | ((x & 0x00FF000000000000ull) >> 40)
|
||||
| ((x & 0x0000FF0000000000ull) >> 24) | ((x & 0x000000FF00000000ull) >> 8)
|
||||
| ((x & 0x00000000FF000000ull) << 8) | ((x & 0x0000000000FF0000ull) << 24)
|
||||
| ((x & 0x000000000000FF00ull) << 40) | ((x & 0x00000000000000FFull) << 56));
|
||||
}
|
||||
# define DRANG_BSWAP16(_X_) (drang_bswap16_impl(_X_))
|
||||
# define DRANG_BSWAP32(_X_) (drang_bswap32_impl(_X_))
|
||||
# define DRANG_BSWAP64(_X_) (drang_bswap64_impl(_X_))
|
||||
#endif
|
||||
|
||||
#define DRANG_BSWAPF(_X_) DRANG_BIT_CAST(DRANG_BSWAP32(DRANG_BIT_CAST(_X_, float, uint32_t)), uint32_t, float)
|
||||
#define DRANG_BSWAPD(_X_) DRANG_BIT_CAST(DRANG_BSWAP64(DRANG_BIT_CAST(_X_, double, uint64_t)), uint64_t, double)
|
||||
|
||||
#if defined(__LITTLE_ENDIAN__)
|
||||
# define DRANG_NE_TO_LE8(_X_) (_X_)
|
||||
# define DRANG_NE_TO_LE16(_X_) (_X_)
|
||||
# define DRANG_NE_TO_LE32(_X_) (_X_)
|
||||
# define DRANG_NE_TO_LE64(_X_) (_X_)
|
||||
# define DRANG_NE_TO_LEF(_X_) (_X_)
|
||||
# define DRANG_NE_TO_LED(_X_) (_X_)
|
||||
|
||||
# define DRANG_LE_TO_NE8(_X_) (_X_)
|
||||
# define DRANG_LE_TO_NE16(_X_) (_X_)
|
||||
# define DRANG_LE_TO_NE32(_X_) (_X_)
|
||||
# define DRANG_LE_TO_NE64(_X_) (_X_)
|
||||
# define DRANG_LE_TO_NEF(_X_) (_X_)
|
||||
# define DRANG_LE_TO_NED(_X_) (_X_)
|
||||
|
||||
# define DRANG_NE_TO_BE8(_X_) DRANG_BSWAP8(_X_)
|
||||
# define DRANG_NE_TO_BE16(_X_) DRANG_BSWAP16(_X_)
|
||||
# define DRANG_NE_TO_BE32(_X_) DRANG_BSWAP32(_X_)
|
||||
# define DRANG_NE_TO_BE64(_X_) DRANG_BSWAP64(_X_)
|
||||
# define DRANG_NE_TO_BEF(_X_) DRANG_BSWAPF(_X_)
|
||||
# define DRANG_NE_TO_BED(_X_) DRANG_BSWAPD(_X_
|
||||
|
||||
# define DRANG_BE_TO_NE8(_X_) DRANG_BSWAP8(_X_)
|
||||
# define DRANG_BE_TO_NE16(_X_) DRANG_BSWAP16(_X_)
|
||||
# define DRANG_BE_TO_NE32(_X_) DRANG_BSWAP32(_X_)
|
||||
# define DRANG_BE_TO_NE64(_X_) DRANG_BSWAP64(_X_)
|
||||
# define DRANG_BE_TO_NEF(_X_) DRANG_BSWAPF(_X_)
|
||||
# define DRANG_BE_TO_NED(_X_) DRANG_BSWAPD(_X_
|
||||
|
||||
#elif defined(__BIG_ENDIAN__)
|
||||
# define DRANG_NE_TO_LE8(_X_) DRANG_BSWAP8(_X_)
|
||||
# define DRANG_NE_TO_LE16(_X_) DRANG_BSWAP16(_X_)
|
||||
# define DRANG_NE_TO_LE32(_X_) DRANG_BSWAP32(_X_)
|
||||
# define DRANG_NE_TO_LE64(_X_) DRANG_BSWAP64(_X_)
|
||||
# define DRANG_NE_TO_LEF(_X_) DRANG_BSWAPF(_X_)
|
||||
# define DRANG_NE_TO_LED(_X_) DRANG_BSWAPD(_X_)
|
||||
|
||||
# define DRANG_LE_TO_NE8(_X_) DRANG_BSWAP8(_X_)
|
||||
# define DRANG_LE_TO_NE16(_X_) DRANG_BSWAP16(_X_)
|
||||
# define DRANG_LE_TO_NE32(_X_) DRANG_BSWAP32(_X_)
|
||||
# define DRANG_LE_TO_NE64(_X_) DRANG_BSWAP64(_X_)
|
||||
# define DRANG_LE_TO_NEF(_X_) DRANG_BSWAPF(_X_)
|
||||
# define DRANG_LE_TO_NED(_X_) DRANG_BSWAPD(_X_
|
||||
|
||||
# define DRANG_NE_TO_BE8(_X_) (_X_)
|
||||
# define DRANG_NE_TO_BE16(_X_) (_X_)
|
||||
# define DRANG_NE_TO_BE32(_X_) (_X_)
|
||||
# define DRANG_NE_TO_BE64(_X_) (_X_)
|
||||
# define DRANG_NE_TO_BEF(_X_) (_X_)
|
||||
# define DRANG_NE_TO_BED(_X_) (_X_)
|
||||
|
||||
# define DRANG_BE_TO_NE8(_X_) (_X_)
|
||||
# define DRANG_BE_TO_NE16(_X_) (_X_)
|
||||
# define DRANG_BE_TO_NE32(_X_) (_X_)
|
||||
# define DRANG_BE_TO_NE64(_X_) (_X_)
|
||||
# define DRANG_BE_TO_NEF(_X_) (_X_)
|
||||
# define DRANG_BE_TO_NED(_X_) (_X_)
|
||||
|
||||
#else
|
||||
# error "Unknown endianness"
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue