From 3fa60d08dee334a536a8361e150ae79bf75f22ab Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 19 Apr 2020 20:44:22 +0200 Subject: [PATCH] Update libretro-common --- libretro-common/include/retro_endianness.h | 461 +++++++++++++++++---- 1 file changed, 390 insertions(+), 71 deletions(-) diff --git a/libretro-common/include/retro_endianness.h b/libretro-common/include/retro_endianness.h index c1dddc31ed..5d66ea2df0 100644 --- a/libretro-common/include/retro_endianness.h +++ b/libretro-common/include/retro_endianness.h @@ -65,6 +65,61 @@ | (((uint64_t)(val) & 0xff00000000000000ULL) >> 56)) #endif + +#if defined (LSB_FIRST) || defined (MSB_FIRST) +# warning Defining MSB_FIRST and LSB_FIRST in compile options is deprecated +# undef LSB_FIRST +# undef MSB_FIRST +#endif + +#ifdef _MSC_VER +# include +# include +#endif + +#if defined (BYTE_ORDER) && defined (BIG_ENDIAN) && defined (LITTLE_ENDIAN) +# if BYTE_ORDER == BIG_ENDIAN +# define MSB_FIRST 1 +# elif BYTE_ORDER == LITTLE_ENDIAN +# define LSB_FIRST 1 +# else +# error "Invalid endianness macros" +# endif +#elif defined (__BYTE_ORDER__) && defined (__ORDER_BIG_ENDIAN__) && defined (__ORDER_LITTLE_ENDIAN__) +# if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +# define MSB_FIRST 1 +# elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# define LSB_FIRST 1 +# else +# error "Invalid endianness macros" +# endif +#elif defined (__i386__) || defined(__x86_64__) +# define LSB_FIRST 1 +#else +# error "Unknown platform" +#endif + +#if defined(MSB_FIRST) && defined(LSB_FIRST) +# error "Bug in LSB_FIRST/MSB_FIRST definition" +#endif + +#if !defined(MSB_FIRST) && !defined(LSB_FIRST) +# error "Bug in LSB_FIRST/MSB_FIRST definition" +#endif + +#ifdef MSB_FIRST +# define RETRO_IS_BIG_ENDIAN 1 +# define RETRO_IS_LITTLE_ENDIAN 0 +/* For compatibility */ +# define WORDS_BIGENDIAN 1 +#else +# define RETRO_IS_BIG_ENDIAN 0 +# define RETRO_IS_LITTLE_ENDIAN 1 +/* For compatibility */ +# undef WORDS_BIGENDIAN +#endif + + /** * is_little_endian: * @@ -73,23 +128,7 @@ * Returns: greater than 0 if little-endian, * otherwise big-endian. **/ -#if defined(MSB_FIRST) -#define is_little_endian() (0) -#elif defined(__x86_64) || defined(__i386) || defined(_M_IX86) || defined(_M_X64) -#define is_little_endian() (1) -#else -static INLINE uint8_t is_little_endian(void) -{ - union - { - uint16_t x; - uint8_t y[2]; - } u; - - u.x = 1; - return u.y[0]; -} -#endif +#define is_little_endian() RETRO_IS_LITTLE_ENDIAN /** * swap_if_big64: @@ -101,17 +140,10 @@ static INLINE uint8_t is_little_endian(void) * otherwise returns same value. **/ -#if defined(MSB_FIRST) +#if RETRO_IS_BIG_ENDIAN #define swap_if_big64(val) (SWAP64(val)) -#elif defined(__x86_64) || defined(__i386) || defined(_M_IX86) || defined(_M_X64) +#elif RETRO_IS_LITTLE_ENDIAN #define swap_if_big64(val) (val) -#else -static INLINE uint64_t swap_if_big64(uint64_t val) -{ - if (is_little_endian()) - return val; - return SWAP64(val); -} #endif /** @@ -124,17 +156,10 @@ static INLINE uint64_t swap_if_big64(uint64_t val) * otherwise returns same value. **/ -#if defined(MSB_FIRST) +#if RETRO_IS_BIG_ENDIAN #define swap_if_big32(val) (SWAP32(val)) -#elif defined(__x86_64) || defined(__i386) || defined(_M_IX86) || defined(_M_X64) +#elif RETRO_IS_LITTLE_ENDIAN #define swap_if_big32(val) (val) -#else -static INLINE uint32_t swap_if_big32(uint32_t val) -{ - if (is_little_endian()) - return val; - return SWAP32(val); -} #endif /** @@ -147,17 +172,10 @@ static INLINE uint32_t swap_if_big32(uint32_t val) * otherwise returns same value. **/ -#if defined(MSB_FIRST) +#if RETRO_IS_BIG_ENDIAN #define swap_if_little64(val) (val) -#elif defined(__x86_64) || defined(__i386) || defined(_M_IX86) || defined(_M_X64) +#elif RETRO_IS_LITTLE_ENDIAN #define swap_if_little64(val) (SWAP64(val)) -#else -static INLINE uint64_t swap_if_little64(uint64_t val) -{ - if (is_little_endian()) - return SWAP64(val); - return val; -} #endif /** @@ -170,17 +188,10 @@ static INLINE uint64_t swap_if_little64(uint64_t val) * otherwise returns same value. **/ -#if defined(MSB_FIRST) +#if RETRO_IS_BIG_ENDIAN #define swap_if_little32(val) (val) -#elif defined(__x86_64) || defined(__i386) || defined(_M_IX86) || defined(_M_X64) +#elif RETRO_IS_LITTLE_ENDIAN #define swap_if_little32(val) (SWAP32(val)) -#else -static INLINE uint32_t swap_if_little32(uint32_t val) -{ - if (is_little_endian()) - return SWAP32(val); - return val; -} #endif /** @@ -193,17 +204,10 @@ static INLINE uint32_t swap_if_little32(uint32_t val) * otherwise returns same value. **/ -#if defined(MSB_FIRST) +#if RETRO_IS_BIG_ENDIAN #define swap_if_big16(val) (SWAP16(val)) -#elif defined(__x86_64) || defined(__i386) || defined(_M_IX86) || defined(_M_X64) +#elif RETRO_IS_LITTLE_ENDIAN #define swap_if_big16(val) (val) -#else -static INLINE uint16_t swap_if_big16(uint16_t val) -{ - if (is_little_endian()) - return val; - return SWAP16(val); -} #endif /** @@ -216,17 +220,10 @@ static INLINE uint16_t swap_if_big16(uint16_t val) * otherwise returns same value. **/ -#if defined(MSB_FIRST) +#if RETRO_IS_BIG_ENDIAN #define swap_if_little16(val) (val) -#elif defined(__x86_64) || defined(__i386) || defined(_M_IX86) || defined(_M_X64) +#elif RETRO_IS_LITTLE_ENDIAN #define swap_if_little16(val) (SWAP16(val)) -#else -static INLINE uint16_t swap_if_little16(uint16_t val) -{ - if (is_little_endian()) - return SWAP16(val); - return val; -} #endif /** @@ -255,4 +252,326 @@ static INLINE uint32_t load32be(const uint32_t *addr) return swap_if_little32(*addr); } +/** + * retro_cpu_to_le16: + * @val : unsigned 16-bit value + * + * Convert unsigned 16-bit value from system to little-endian. + * + * Returns: Little-endian represantation of val. + **/ + +#define retro_cpu_to_le16(val) swap_if_big16(val) + +/** + * retro_cpu_to_le32: + * @val : unsigned 32-bit value + * + * Convert unsigned 32-bit value from system to little-endian. + * + * Returns: Little-endian represantation of val. + **/ + +#define retro_cpu_to_le32(val) swap_if_big32(val) + +/** + * retro_cpu_to_le64: + * @val : unsigned 64-bit value + * + * Convert unsigned 64-bit value from system to little-endian. + * + * Returns: Little-endian represantation of val. + **/ + +#define retro_cpu_to_le64(val) swap_if_big64(val) + +/** + * retro_le_to_cpu16: + * @val : unsigned 16-bit value + * + * Convert unsigned 16-bit value from little-endian to native. + * + * Returns: Native represantation of little-endian val. + **/ + +#define retro_le_to_cpu16(val) swap_if_big16(val) + +/** + * retro_le_to_cpu32: + * @val : unsigned 32-bit value + * + * Convert unsigned 32-bit value from little-endian to native. + * + * Returns: Native represantation of little-endian val. + **/ + +#define retro_le_to_cpu32(val) swap_if_big32(val) + +/** + * retro_le_to_cpu16: + * @val : unsigned 64-bit value + * + * Convert unsigned 64-bit value from little-endian to native. + * + * Returns: Native represantation of little-endian val. + **/ + +#define retro_le_to_cpu64(val) swap_if_big64(val) + +/** + * retro_cpu_to_be16: + * @val : unsigned 16-bit value + * + * Convert unsigned 16-bit value from system to big-endian. + * + * Returns: Big-endian represantation of val. + **/ + +#define retro_cpu_to_be16(val) swap_if_little16(val) + +/** + * retro_cpu_to_be32: + * @val : unsigned 32-bit value + * + * Convert unsigned 32-bit value from system to big-endian. + * + * Returns: Big-endian represantation of val. + **/ + +#define retro_cpu_to_be32(val) swap_if_little32(val) + +/** + * retro_cpu_to_be64: + * @val : unsigned 64-bit value + * + * Convert unsigned 64-bit value from system to big-endian. + * + * Returns: Big-endian represantation of val. + **/ + +#define retro_cpu_to_be64(val) swap_if_little64(val) + +/** + * retro_be_to_cpu16: + * @val : unsigned 16-bit value + * + * Convert unsigned 16-bit value from big-endian to native. + * + * Returns: Native represantation of big-endian val. + **/ + +#define retro_be_to_cpu16(val) swap_if_little16(val) + +/** + * retro_be_to_cpu32: + * @val : unsigned 32-bit value + * + * Convert unsigned 32-bit value from big-endian to native. + * + * Returns: Native represantation of big-endian val. + **/ + +#define retro_be_to_cpu32(val) swap_if_little32(val) + +/** + * retro_be_to_cpu64: + * @val : unsigned 64-bit value + * + * Convert unsigned 64-bit value from big-endian to native. + * + * Returns: Native represantation of big-endian val. + **/ + +#define retro_be_to_cpu64(val) swap_if_little64(val) + +#ifdef __GNUC__ +/* This attribute means that the same memory may be referred through + pointers to different size of the object (aliasing). E.g. that u8 * + and u32 * may actually be pointing to the same object. */ +#define MAY_ALIAS __attribute__((__may_alias__)) +#else +#define MAY_ALIAS +#endif + +#pragma pack(push, 1) +struct retro_unaligned_uint16_s +{ + uint16_t val; +} MAY_ALIAS; +struct retro_unaligned_uint32_s +{ + uint32_t val; +} MAY_ALIAS; +struct retro_unaligned_uint64_s +{ + uint64_t val; +} MAY_ALIAS; +#pragma pack(pop) + +typedef struct retro_unaligned_uint16_s retro_unaligned_uint16_t; +typedef struct retro_unaligned_uint32_s retro_unaligned_uint32_t; +typedef struct retro_unaligned_uint64_s retro_unaligned_uint64_t; + +/* L-value references to unaligned pointers. */ +#define retro_unaligned16(p) (((retro_unaligned_uint16_t *)p)->val) +#define retro_unaligned32(p) (((retro_unaligned_uint32_t *)p)->val) +#define retro_unaligned64(p) (((retro_unaligned_uint64_t *)p)->val) + +/** + * retro_get_unaligned_16be: + * @addr : pointer to unsigned 16-bit value + * + * Convert unsigned unaligned 16-bit value from big-endian to native. + * + * Returns: Native represantation of big-endian val. + **/ + +static INLINE uint16_t retro_get_unaligned_16be(void *addr) { + return retro_be_to_cpu16(retro_unaligned16(addr)); +} + +/** + * retro_get_unaligned_32be: + * @addr : pointer to unsigned 32-bit value + * + * Convert unsigned unaligned 32-bit value from big-endian to native. + * + * Returns: Native represantation of big-endian val. + **/ + +static INLINE uint32_t retro_get_unaligned_32be(void *addr) { + return retro_be_to_cpu32(retro_unaligned32(addr)); +} + +/** + * retro_get_unaligned_64be: + * @addr : pointer to unsigned 64-bit value + * + * Convert unsigned unaligned 64-bit value from big-endian to native. + * + * Returns: Native represantation of big-endian val. + **/ + +static INLINE uint64_t retro_get_unaligned_64be(void *addr) { + return retro_be_to_cpu64(retro_unaligned64(addr)); +} + +/** + * retro_get_unaligned_16le: + * @addr : pointer to unsigned 16-bit value + * + * Convert unsigned unaligned 16-bit value from little-endian to native. + * + * Returns: Native represantation of little-endian val. + **/ + +static INLINE uint16_t retro_get_unaligned_16le(void *addr) { + return retro_le_to_cpu16(retro_unaligned16(addr)); +} + +/** + * retro_get_unaligned_32le: + * @addr : pointer to unsigned 32-bit value + * + * Convert unsigned unaligned 32-bit value from little-endian to native. + * + * Returns: Native represantation of little-endian val. + **/ + +static INLINE uint32_t retro_get_unaligned_32le(void *addr) { + return retro_le_to_cpu32(retro_unaligned32(addr)); +} + +/** + * retro_get_unaligned_64le: + * @addr : pointer to unsigned 64-bit value + * + * Convert unsigned unaligned 64-bit value from little-endian to native. + * + * Returns: Native represantation of little-endian val. + **/ + +static INLINE uint64_t retro_get_unaligned_64le(void *addr) { + return retro_le_to_cpu64(retro_unaligned64(addr)); +} + +/** + * retro_set_unaligned_16le: + * @addr : pointer to unsigned 16-bit value + * @val : value to store + * + * Convert native value to unsigned unaligned 16-bit little-endian value + * + **/ + +static INLINE void retro_set_unaligned_16le(void *addr, uint16_t v) { + retro_unaligned16(addr) = retro_cpu_to_le16(v); +} + +/** + * retro_set_unaligned_32le: + * @addr : pointer to unsigned 32-bit value + * @val : value to store + * + * Convert native value to unsigned unaligned 32-bit little-endian value + * + **/ + +static INLINE void retro_set_unaligned_32le(void *addr, uint32_t v) { + retro_unaligned32(addr) = retro_cpu_to_le32(v); +} + +/** + * retro_set_unaligned_32le: + * @addr : pointer to unsigned 32-bit value + * @val : value to store + * + * Convert native value to unsigned unaligned 32-bit little-endian value + * + **/ + +static INLINE void retro_set_unaligned_64le(void *addr, uint64_t v) { + retro_unaligned64(addr) = retro_cpu_to_le64(v); +} + +/** + * retro_set_unaligned_16be: + * @addr : pointer to unsigned 16-bit value + * @val : value to store + * + * Convert native value to unsigned unaligned 16-bit big-endian value + * + **/ + +static INLINE void retro_set_unaligned_16be(void *addr, uint16_t v) { + retro_unaligned16(addr) = retro_cpu_to_be16(v); +} + +/** + * retro_set_unaligned_32be: + * @addr : pointer to unsigned 32-bit value + * @val : value to store + * + * Convert native value to unsigned unaligned 32-bit big-endian value + * + **/ + +static INLINE void retro_set_unaligned_32be(void *addr, uint32_t v) { + retro_unaligned32(addr) = retro_cpu_to_be32(v); +} + +/** + * retro_set_unaligned_32be: + * @addr : pointer to unsigned 32-bit value + * @val : value to store + * + * Convert native value to unsigned unaligned 32-bit big-endian value + * + **/ + +static INLINE void retro_set_unaligned_64be(void *addr, uint64_t v) { + retro_unaligned64(addr) = retro_cpu_to_be64(v); +} + + #endif