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.
Specifically, I want to port [wavinfo] from ext13.
.hc
On Wed, 26 Feb 2003, 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.
suppose you have:
char data[4]; /* float data directly from a file */
then this is wrong:
*(float *)data
you have to do this:
1. "convert" to native integer
1.1. from little-endian: int x = data[0] | (data[1]<<8) | (data[2]<<16) | (data[3]<<24);
1.2. from big-endian: int x = data[3] | (data[2]<<8) | (data[1]<<16) | (data[0]<<24);
2. "convert" to float *(float *)&x
this works in similar fashion for reading other number types, except for "short" the formulas are shorter, and for "double" and "long long" the formulas are longer. step 1 needs to be done on an integer type of the same size as the data. step 2 is useless if desired result is an integer type...
GridFlow has been tested on a few bigendians: Sun, SGI, Mac. However I fear the code I'd extract from it wouldn't be too obvious. I hope the above explanation is sufficient.
________________________________________________________________ Mathieu Bouchard http://artengine.ca/matju
On Wed, 26 Feb 2003, Mathieu Bouchard wrote:
suppose you have: char data[4]; /* float data directly from a file */ int x = data[0] | (data[1]<<8) | (data[2]<<16) | (data[3]<<24);
a little amendment: the type of "data" must be unsigned char, else the conversion of step 1 will be wrong. however the signedness of the type of "x" does not matter.
Tigital's code may be faster than mine (or some parts of it may be, i don't know) if you accept the fact that it contains mac-only code.
________________________________________________________________ Mathieu Bouchard http://artengine.ca/matju
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