Index: SDL_endian.h =================================================================== RCS file: /home/sdlweb/libsdl.org/cvs/SDL12/include/SDL_endian.h,v retrieving revision 1.6 retrieving revision 1.11 diff -u -r1.6 -r1.11 --- SDL_endian.h 4 Jan 2004 16:49:07 -0000 1.6 +++ SDL_endian.h 27 Nov 2004 23:11:20 -0000 1.11 @@ -22,7 +22,7 @@ #ifdef SAVE_RCSID static char rcsid = - "@(#) $Id: SDL_endian.h,v 1.6 2004/01/04 16:49:07 slouken Exp $"; + "@(#) $Id: SDL_endian.h,v 1.11 2004/11/27 23:11:20 pmandin Exp $"; #endif /* Functions for reading and writing endian-specific values */ @@ -54,55 +54,118 @@ extern "C" { #endif -/* The macros used to swap values */ -/* Try to use superfast macros on systems that support them */ -#ifdef linux -#include -#ifdef __arch__swab16 -#define SDL_Swap16 __arch__swab16 -#endif -#ifdef __arch__swab32 -#define SDL_Swap32 __arch__swab32 -#endif -#endif /* linux */ /* Use inline functions for compilers that support them, and static functions for those that do not. Because these functions become static for compilers that do not support inline functions, this header should only be included in files that actually use them. */ -#ifndef SDL_Swap16 -static __inline__ Uint16 SDL_Swap16(Uint16 D) { - return((D<<8)|(D>>8)); +#if defined(__GNUC__) && defined(__i386__) +static __inline__ Uint16 SDL_Swap16(Uint16 x) +{ + __asm__("xchgb %b0,%h0" : "=q" (x) : "0" (x)); + return x; +} +#elif defined(__GNUC__) && defined(__x86_64__) +static __inline__ Uint16 SDL_Swap16(Uint16 x) +{ + __asm__("xchgb %b0,%h0" : "=q" (x) : "0" (x)); + return x; +} +#elif defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__)) +static __inline__ Uint16 SDL_Swap16(Uint16 x) +{ + Uint16 result; + + __asm__("rlwimi %0,%2,8,16,23" : "=&r" (result) : "0" (x >> 8), "r" (x)); + return result; +} +#elif defined(__GNUC__) && defined(__M68000__) +static __inline__ Uint16 SDL_Swap16(Uint16 x) +{ + __asm__("rorw #8,%0" : "=d" (x) : "0" (x) : "cc"); + return x; +} +#else +static __inline__ Uint16 SDL_Swap16(Uint16 x) { + return((x<<8)|(x>>8)); } #endif -#ifndef SDL_Swap32 -static __inline__ Uint32 SDL_Swap32(Uint32 D) { - return((D<<24)|((D<<8)&0x00FF0000)|((D>>8)&0x0000FF00)|(D>>24)); + +#if defined(__GNUC__) && defined(__i386__) +static __inline__ Uint32 SDL_Swap32(Uint32 x) +{ + __asm__("bswap %0" : "=r" (x) : "0" (x)); + return x; +} +#elif defined(__GNUC__) && defined(__x86_64__) +static __inline__ Uint32 SDL_Swap32(Uint32 x) +{ + __asm__("bswapl %0" : "=r" (x) : "0" (x)); + return x; +} +#elif defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__)) +static __inline__ Uint32 SDL_Swap32(Uint32 x) +{ + Uint32 result; + + __asm__("rlwimi %0,%2,24,16,23" : "=&r" (result) : "0" (x>>24), "r" (x)); + __asm__("rlwimi %0,%2,8,8,15" : "=&r" (result) : "0" (result), "r" (x)); + __asm__("rlwimi %0,%2,24,0,7" : "=&r" (result) : "0" (result), "r" (x)); + return result; +} +#elif defined(__GNUC__) && defined(__M68000__) +static __inline__ Uint32 SDL_Swap32(Uint32 x) +{ + __asm__("rorw #8,%0\n\tswap %0\n\tror #8,%0" : "=d" (x) : "0" (x) : "cc"); + return x; +} +#else +static __inline__ Uint32 SDL_Swap32(Uint32 x) { + return((x<<24)|((x<<8)&0x00FF0000)|((x>>8)&0x0000FF00)|(x>>24)); } #endif + #ifdef SDL_HAS_64BIT_TYPE -#ifndef SDL_Swap64 -static __inline__ Uint64 SDL_Swap64(Uint64 val) { +#if defined(__GNUC__) && defined(__i386__) +static __inline__ Uint64 SDL_Swap64(Uint64 x) +{ + union { + struct { Uint32 a,b; } s; + Uint64 u; + } v; + v.u = x; + __asm__("bswapl %0 ; bswapl %1 ; xchgl %0,%1" + : "=r" (v.s.a), "=r" (v.s.b) + : "0" (v.s.a), "1" (v.s.b)); + return v.u; +} +#elif defined(__GNUC__) && defined(__x86_64__) +static __inline__ Uint64 SDL_Swap64(Uint64 x) +{ + __asm__("bswapq %0" : "=r" (x) : "0" (x)); + return x; +} +#else +static __inline__ Uint64 SDL_Swap64(Uint64 x) +{ Uint32 hi, lo; /* Separate into high and low 32-bit values and swap them */ - lo = (Uint32)(val&0xFFFFFFFF); - val >>= 32; - hi = (Uint32)(val&0xFFFFFFFF); - val = SDL_Swap32(lo); - val <<= 32; - val |= SDL_Swap32(hi); - return(val); + lo = (Uint32)(x&0xFFFFFFFF); + x >>= 32; + hi = (Uint32)(x&0xFFFFFFFF); + x = SDL_Swap32(lo); + x <<= 32; + x |= SDL_Swap32(hi); + return(x); } #endif #else -#ifndef SDL_Swap64 /* This is mainly to keep compilers from complaining in SDL code. If there is no real 64-bit datatype, then compilers will complain about the fake 64-bit datatype that SDL provides when it compiles user code. */ #define SDL_Swap64(X) (X) -#endif #endif /* SDL_HAS_64BIT_TYPE */