include/SDL_endian.h
author Sam Lantinga <slouken@libsdl.org>
Sat, 18 Feb 2006 06:51:00 +0000
changeset 1368 533567cbb576
parent 1354 22f39393668a
child 1369 42eeb14770e3
permissions -rw-r--r--
More fixes for building on BeOS
     1 /*
     2     SDL - Simple DirectMedia Layer
     3     Copyright (C) 1997-2006 Sam Lantinga
     4 
     5     This library is free software; you can redistribute it and/or
     6     modify it under the terms of the GNU Lesser General Public
     7     License as published by the Free Software Foundation; either
     8     version 2.1 of the License, or (at your option) any later version.
     9 
    10     This library is distributed in the hope that it will be useful,
    11     but WITHOUT ANY WARRANTY; without even the implied warranty of
    12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13     Lesser General Public License for more details.
    14 
    15     You should have received a copy of the GNU Lesser General Public
    16     License along with this library; if not, write to the Free Software
    17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    18 
    19     Sam Lantinga
    20     slouken@libsdl.org
    21 */
    22 
    23 /* Functions for reading and writing endian-specific values */
    24 
    25 #ifndef _SDL_endian_h
    26 #define _SDL_endian_h
    27 
    28 #include "SDL_stdinc.h"
    29 
    30 /* The two types of endianness */
    31 #define SDL_LIL_ENDIAN	1234
    32 #define SDL_BIG_ENDIAN	4321
    33 
    34 #ifndef SDL_BYTEORDER	/* Not defined in SDL_config.h? */
    35 #if (defined(__i386__) || defined(__i386)) || \
    36      defined(__ia64__) || defined(__x86_64__) || \
    37     (defined(__alpha__) || defined(__alpha)) || \
    38     (defined(__arm__) || defined(__thumb__)) || \
    39     (defined(__sh__) || defined(__sh64__)) || \
    40     (defined(__mips__) && defined(__MIPSEL__)) || \
    41      defined(__SYMBIAN32__) || defined(__OS2__)
    42 #define SDL_BYTEORDER	SDL_LIL_ENDIAN
    43 #else
    44 #define SDL_BYTEORDER	SDL_BIG_ENDIAN
    45 #endif
    46 #endif /* !SDL_BYTEORDER */
    47 
    48 
    49 #include "begin_code.h"
    50 /* Set up for C function definitions, even when using C++ */
    51 #ifdef __cplusplus
    52 extern "C" {
    53 #endif
    54 
    55 /* Use __inline__ functions for compilers that support them, and static
    56    functions for those that do not.  Because these functions become
    57    static for compilers that do not support __inline__ functions, this
    58    header should only be included in files that actually use them.
    59 */
    60 #if defined(__GNUC__) && defined(__i386__) &&
    61    !(__GNUC__ == 2 && __GNUC_MINOR__ == 95 /* broken gcc version */)
    62 static __inline__ Uint16 SDL_Swap16(Uint16 x)
    63 {
    64 	__asm__("xchgb %b0,%h0" : "=q" (x) :  "0" (x));
    65 	return x;
    66 }
    67 #elif defined(__GNUC__) && defined(__x86_64__)
    68 static __inline__ Uint16 SDL_Swap16(Uint16 x)
    69 {
    70 	__asm__("xchgb %b0,%h0" : "=Q" (x) :  "0" (x));
    71 	return x;
    72 }
    73 #elif defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__))
    74 static __inline__ Uint16 SDL_Swap16(Uint16 x)
    75 {
    76 	Uint16 result;
    77 
    78 	__asm__("rlwimi %0,%2,8,16,23" : "=&r" (result) : "0" (x >> 8), "r" (x));
    79 	return result;
    80 }
    81 #elif defined(__GNUC__) && (defined(__M68000__) || defined(__M68020__))
    82 static __inline__ Uint16 SDL_Swap16(Uint16 x)
    83 {
    84 	__asm__("rorw #8,%0" : "=d" (x) :  "0" (x) : "cc");
    85 	return x;
    86 }
    87 #else
    88 static __inline__ Uint16 SDL_Swap16(Uint16 x) {
    89 	return((x<<8)|(x>>8));
    90 }
    91 #endif
    92 
    93 #if defined(__GNUC__) && defined(__i386__)
    94 static __inline__ Uint32 SDL_Swap32(Uint32 x)
    95 {
    96 	__asm__("bswap %0" : "=r" (x) : "0" (x));
    97 	return x;
    98 }
    99 #elif defined(__GNUC__) && defined(__x86_64__)
   100 static __inline__ Uint32 SDL_Swap32(Uint32 x)
   101 {
   102 	__asm__("bswapl %0" : "=r" (x) : "0" (x));
   103 	return x;
   104 }
   105 #elif defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__))
   106 static __inline__ Uint32 SDL_Swap32(Uint32 x)
   107 {
   108 	Uint32 result;
   109 
   110 	__asm__("rlwimi %0,%2,24,16,23" : "=&r" (result) : "0" (x>>24), "r" (x));
   111 	__asm__("rlwimi %0,%2,8,8,15"   : "=&r" (result) : "0" (result),    "r" (x));
   112 	__asm__("rlwimi %0,%2,24,0,7"   : "=&r" (result) : "0" (result),    "r" (x));
   113 	return result;
   114 }
   115 #elif defined(__GNUC__) && (defined(__M68000__) || defined(__M68020__))
   116 static __inline__ Uint32 SDL_Swap32(Uint32 x)
   117 {
   118 	__asm__("rorw #8,%0\n\tswap %0\n\trorw #8,%0" : "=d" (x) :  "0" (x) : "cc");
   119 	return x;
   120 }
   121 #else
   122 static __inline__ Uint32 SDL_Swap32(Uint32 x) {
   123 	return((x<<24)|((x<<8)&0x00FF0000)|((x>>8)&0x0000FF00)|(x>>24));
   124 }
   125 #endif
   126 
   127 #ifdef SDL_HAS_64BIT_TYPE
   128 #if defined(__GNUC__) && defined(__i386__)
   129 static __inline__ Uint64 SDL_Swap64(Uint64 x)
   130 {
   131 	union { 
   132 		struct { Uint32 a,b; } s;
   133 		Uint64 u;
   134 	} v;
   135 	v.u = x;
   136 	__asm__("bswapl %0 ; bswapl %1 ; xchgl %0,%1" 
   137 	        : "=r" (v.s.a), "=r" (v.s.b) 
   138 	        : "0" (v.s.a), "1" (v.s.b)); 
   139 	return v.u;
   140 }
   141 #elif defined(__GNUC__) && defined(__x86_64__)
   142 static __inline__ Uint64 SDL_Swap64(Uint64 x)
   143 {
   144 	__asm__("bswapq %0" : "=r" (x) : "0" (x));
   145 	return x;
   146 }
   147 #else
   148 static __inline__ Uint64 SDL_Swap64(Uint64 x)
   149 {
   150 	Uint32 hi, lo;
   151 
   152 	/* Separate into high and low 32-bit values and swap them */
   153 	lo = (Uint32)(x&0xFFFFFFFF);
   154 	x >>= 32;
   155 	hi = (Uint32)(x&0xFFFFFFFF);
   156 	x = SDL_Swap32(lo);
   157 	x <<= 32;
   158 	x |= SDL_Swap32(hi);
   159 	return(x);
   160 }
   161 #endif
   162 #else
   163 /* This is mainly to keep compilers from complaining in SDL code.
   164    If there is no real 64-bit datatype, then compilers will complain about
   165    the fake 64-bit datatype that SDL provides when it compiles user code.
   166 */
   167 #define SDL_Swap64(X)	(X)
   168 #endif /* SDL_HAS_64BIT_TYPE */
   169 
   170 
   171 /* Byteswap item from the specified endianness to the native endianness */
   172 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
   173 #define SDL_SwapLE16(X)	(X)
   174 #define SDL_SwapLE32(X)	(X)
   175 #define SDL_SwapLE64(X)	(X)
   176 #define SDL_SwapBE16(X)	SDL_Swap16(X)
   177 #define SDL_SwapBE32(X)	SDL_Swap32(X)
   178 #define SDL_SwapBE64(X)	SDL_Swap64(X)
   179 #else
   180 #define SDL_SwapLE16(X)	SDL_Swap16(X)
   181 #define SDL_SwapLE32(X)	SDL_Swap32(X)
   182 #define SDL_SwapLE64(X)	SDL_Swap64(X)
   183 #define SDL_SwapBE16(X)	(X)
   184 #define SDL_SwapBE32(X)	(X)
   185 #define SDL_SwapBE64(X)	(X)
   186 #endif
   187 
   188 /* Ends C function definitions when using C++ */
   189 #ifdef __cplusplus
   190 }
   191 #endif
   192 #include "close_code.h"
   193 
   194 #endif /* _SDL_endian_h */