Path: blob/main/system/include/SDL/SDL_endian.h
6169 views
/*1Simple DirectMedia Layer2Copyright (C) 1997-2011 Sam Lantinga <[email protected]>34This software is provided 'as-is', without any express or implied5warranty. In no event will the authors be held liable for any damages6arising from the use of this software.78Permission is granted to anyone to use this software for any purpose,9including commercial applications, and to alter it and redistribute it10freely, subject to the following restrictions:11121. The origin of this software must not be misrepresented; you must not13claim that you wrote the original software. If you use this software14in a product, an acknowledgment in the product documentation would be15appreciated but is not required.162. Altered source versions must be plainly marked as such, and must not be17misrepresented as being the original software.183. This notice may not be removed or altered from any source distribution.19*/2021/**22* \file SDL_endian.h23*24* Functions for reading and writing endian-specific values25*/2627#ifndef _SDL_endian_h28#define _SDL_endian_h2930#include "SDL_stdinc.h"3132/**33* \name The two types of endianness34*/35/*@{*/36#define SDL_LIL_ENDIAN 123437#define SDL_BIG_ENDIAN 432138/*@}*/3940#ifndef SDL_BYTEORDER /* Not defined in SDL_config.h? */41#ifdef __linux__42#include <endian.h>43#define SDL_BYTEORDER __BYTE_ORDER44#else /* __linux __ */45#if defined(__hppa__) || \46defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || \47(defined(__MIPS__) && defined(__MISPEB__)) || \48defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC) || \49defined(__sparc__)50#define SDL_BYTEORDER SDL_BIG_ENDIAN51#else52#define SDL_BYTEORDER SDL_LIL_ENDIAN53#endif54#endif /* __linux __ */55#endif /* !SDL_BYTEORDER */565758#include "begin_code.h"59/* Set up for C function definitions, even when using C++ */60#ifdef __cplusplus61/* *INDENT-OFF* */62extern "C" {63/* *INDENT-ON* */64#endif6566/**67* \file SDL_endian.h68*69* Uses inline functions for compilers that support them, and static70* functions for those that do not. Because these functions become71* static for compilers that do not support inline functions, this72* header should only be included in files that actually use them.73*/74#if defined(__GNUC__) && defined(__i386__) && \75!(__GNUC__ == 2 && __GNUC_MINOR__ == 95 /* broken gcc version */)76static __inline__ Uint1677SDL_Swap16(Uint16 x)78{79__asm__("xchgb %b0,%h0": "=q"(x):"0"(x));80return x;81}82#elif defined(__GNUC__) && defined(__x86_64__)83static __inline__ Uint1684SDL_Swap16(Uint16 x)85{86__asm__("xchgb %b0,%h0": "=Q"(x):"0"(x));87return x;88}89#elif defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__))90static __inline__ Uint1691SDL_Swap16(Uint16 x)92{93Uint16 result;9495__asm__("rlwimi %0,%2,8,16,23": "=&r"(result):"0"(x >> 8), "r"(x));96return result;97}98#elif defined(__GNUC__) && (defined(__M68000__) || defined(__M68020__)) && !defined(__mcoldfire__)99static __inline__ Uint16100SDL_Swap16(Uint16 x)101{102__asm__("rorw #8,%0": "=d"(x): "0"(x):"cc");103return x;104}105#else106static __inline__ Uint16107SDL_Swap16(Uint16 x)108{109return SDL_static_cast(Uint16, ((x << 8) | (x >> 8)));110}111#endif112113#if defined(__GNUC__) && defined(__i386__)114static __inline__ Uint32115SDL_Swap32(Uint32 x)116{117__asm__("bswap %0": "=r"(x):"0"(x));118return x;119}120#elif defined(__GNUC__) && defined(__x86_64__)121static __inline__ Uint32122SDL_Swap32(Uint32 x)123{124__asm__("bswapl %0": "=r"(x):"0"(x));125return x;126}127#elif defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__))128static __inline__ Uint32129SDL_Swap32(Uint32 x)130{131Uint32 result;132133__asm__("rlwimi %0,%2,24,16,23": "=&r"(result):"0"(x >> 24), "r"(x));134__asm__("rlwimi %0,%2,8,8,15": "=&r"(result):"0"(result), "r"(x));135__asm__("rlwimi %0,%2,24,0,7": "=&r"(result):"0"(result), "r"(x));136return result;137}138#elif defined(__GNUC__) && (defined(__M68000__) || defined(__M68020__)) && !defined(__mcoldfire__)139static __inline__ Uint32140SDL_Swap32(Uint32 x)141{142__asm__("rorw #8,%0\n\tswap %0\n\trorw #8,%0": "=d"(x): "0"(x):"cc");143return x;144}145#else146static __inline__ Uint32147SDL_Swap32(Uint32 x)148{149return SDL_static_cast(Uint32, ((x << 24) | ((x << 8) & 0x00FF0000) |150((x >> 8) & 0x0000FF00) | (x >> 24)));151}152#endif153154#if defined(__GNUC__) && defined(__i386__)155static __inline__ Uint64156SDL_Swap64(Uint64 x)157{158union159{160struct161{162Uint32 a, b;163} s;164Uint64 u;165} v;166v.u = x;167__asm__("bswapl %0 ; bswapl %1 ; xchgl %0,%1": "=r"(v.s.a), "=r"(v.s.b):"0"(v.s.a),168"1"(v.s.169b));170return v.u;171}172#elif defined(__GNUC__) && defined(__x86_64__)173static __inline__ Uint64174SDL_Swap64(Uint64 x)175{176__asm__("bswapq %0": "=r"(x):"0"(x));177return x;178}179#else180static __inline__ Uint64181SDL_Swap64(Uint64 x)182{183Uint32 hi, lo;184185/* Separate into high and low 32-bit values and swap them */186lo = SDL_static_cast(Uint32, x & 0xFFFFFFFF);187x >>= 32;188hi = SDL_static_cast(Uint32, x & 0xFFFFFFFF);189x = SDL_Swap32(lo);190x <<= 32;191x |= SDL_Swap32(hi);192return (x);193}194#endif195196197static __inline__ float198SDL_SwapFloat(float x)199{200union201{202float f;203Uint32 ui32;204} swapper;205swapper.f = x;206swapper.ui32 = SDL_Swap32(swapper.ui32);207return swapper.f;208}209210211/**212* \name Swap to native213* Byteswap item from the specified endianness to the native endianness.214*/215/*@{*/216#if SDL_BYTEORDER == SDL_LIL_ENDIAN217#define SDL_SwapLE16(X) (X)218#define SDL_SwapLE32(X) (X)219#define SDL_SwapLE64(X) (X)220#define SDL_SwapFloatLE(X) (X)221#define SDL_SwapBE16(X) SDL_Swap16(X)222#define SDL_SwapBE32(X) SDL_Swap32(X)223#define SDL_SwapBE64(X) SDL_Swap64(X)224#define SDL_SwapFloatBE(X) SDL_SwapFloat(X)225#else226#define SDL_SwapLE16(X) SDL_Swap16(X)227#define SDL_SwapLE32(X) SDL_Swap32(X)228#define SDL_SwapLE64(X) SDL_Swap64(X)229#define SDL_SwapFloatLE(X) SDL_SwapFloat(X)230#define SDL_SwapBE16(X) (X)231#define SDL_SwapBE32(X) (X)232#define SDL_SwapBE64(X) (X)233#define SDL_SwapFloatBE(X) (X)234#endif235/*@}*//*Swap to native*/236237/* Ends C function definitions when using C++ */238#ifdef __cplusplus239/* *INDENT-OFF* */240}241/* *INDENT-ON* */242#endif243#include "close_code.h"244245#endif /* _SDL_endian_h */246247/* vi: set ts=4 sw=4 expandtab: */248249250