On Wednesday, February 26, 2003, at 01:16 AM, Hans-Christoph Steiner wrote:
In effort to learn how to port stuff to MacOS X, I was hoping someone could point me to a piece of code where endianness is an issue and has been ported to PowerPC. I always learn best by following an good example.
hi hc,
...oddly enough, I don't there was any endian swapping necessary for the GEM OSX port...but I've done plenty of other ports where it's essential...all that is required is a set of functions to convert from (and to) int, short, and float: char's usually don't need to be swapped...anyway, here are the equations I use, which are from the libSDL, except for the float stuff:
#ifndef SDL_Swap16 static __inline__ Uint16 SDL_Swap16(Uint16 D) { return((D<<8)|(D>>8)); } #endif #ifndef SDL_Swap32 static __inline__ Uint32 SDL_Swap32(Uint32 D) { return((D<<24)|((D<<8)&0x00FF0000)|((D>>8)&0x0000FF00)|(D>>24)); } #endif #ifdef SDL_HAS_64BIT_TYPE #ifndef SDL_Swap64 static __inline__ Uint64 SDL_Swap64(Uint64 val) { 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); } #endif #endif
inline float LoadLEFloat( float *f ) { #if ! defined( __MWERKS__ ) //Usage: void __stwbrx( unsigned int, unsigned int *address, int byteOffsetFromAddress ); #define __stwbrx( value, base, index ) \ __asm__ ( "stwbrx %0, %1, %2" : : "r" (value), "b%" (index), "r" (base) : "memory" ) #endif
union { long i; float f; }transfer; //load the float into the integer unit unsigned int temp = ((long*) f)[0];
//store it to the transfer union, with byteswapping __stwbrx( temp, &transfer.i, 0);
//load it into the FPU and return it return transfer.f; }
...don't forget: if you swap on load to disk, swap again on write to disk...otherwise it'll only work alternating times! Also, if ya wanna be tricky, you can make a set of defines that work based on a test of the system for endianness:
#if SDL_BYTEORDER == SDL_LIL_ENDIAN #define LoadLEFloat(X) (X) #else #define LoadLEFloat(X) LoadLEFloat(X) #endif
...this way, the compiler makes the right decision, and there's less impact on code bloat...
l8r, jamie