include/SDL_endian.h
changeset 1895 c121d94672cb
parent 1475 d45aefcac017
child 1984 b910bcabec26
equal deleted inserted replaced
1894:c69cee13dd76 1895:c121d94672cb
    18 
    18 
    19     Sam Lantinga
    19     Sam Lantinga
    20     slouken@libsdl.org
    20     slouken@libsdl.org
    21 */
    21 */
    22 
    22 
    23 /* Functions for reading and writing endian-specific values */
    23 /**
       
    24  * \file SDL_endian.h
       
    25  *
       
    26  * Functions for reading and writing endian-specific values
       
    27  */
    24 
    28 
    25 #ifndef _SDL_endian_h
    29 #ifndef _SDL_endian_h
    26 #define _SDL_endian_h
    30 #define _SDL_endian_h
    27 
    31 
    28 #include "SDL_stdinc.h"
    32 #include "SDL_stdinc.h"
    29 
    33 
    30 /* The two types of endianness */
    34 /* The two types of endianness */
    31 #define SDL_LIL_ENDIAN	1234
    35 #define SDL_LIL_ENDIAN	1234
    32 #define SDL_BIG_ENDIAN	4321
    36 #define SDL_BIG_ENDIAN	4321
    33 
    37 
    34 #ifndef SDL_BYTEORDER	/* Not defined in SDL_config.h? */
    38 #ifndef SDL_BYTEORDER           /* Not defined in SDL_config.h? */
    35 #if defined(__hppa__) || \
    39 #if defined(__hppa__) || \
    36     defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || \
    40     defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || \
    37     (defined(__MIPS__) && defined(__MISPEB__)) || \
    41     (defined(__MIPS__) && defined(__MISPEB__)) || \
    38     defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC) || \
    42     defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC) || \
    39     defined(__sparc__)
    43     defined(__sparc__)
    45 
    49 
    46 
    50 
    47 #include "begin_code.h"
    51 #include "begin_code.h"
    48 /* Set up for C function definitions, even when using C++ */
    52 /* Set up for C function definitions, even when using C++ */
    49 #ifdef __cplusplus
    53 #ifdef __cplusplus
       
    54 /* *INDENT-OFF* */
    50 extern "C" {
    55 extern "C" {
       
    56 /* *INDENT-ON* */
    51 #endif
    57 #endif
    52 
    58 
    53 /* Use inline functions for compilers that support them, and static
    59 /* Use inline functions for compilers that support them, and static
    54    functions for those that do not.  Because these functions become
    60    functions for those that do not.  Because these functions become
    55    static for compilers that do not support inline functions, this
    61    static for compilers that do not support inline functions, this
    56    header should only be included in files that actually use them.
    62    header should only be included in files that actually use them.
    57 */
    63 */
    58 #if defined(__GNUC__) && defined(__i386__) && \
    64 #if defined(__GNUC__) && defined(__i386__) && \
    59    !(__GNUC__ == 2 && __GNUC_MINOR__ == 95 /* broken gcc version */)
    65    !(__GNUC__ == 2 && __GNUC_MINOR__ == 95 /* broken gcc version */)
    60 static __inline__ Uint16 SDL_Swap16(Uint16 x)
    66 static __inline__ Uint16
    61 {
    67 SDL_Swap16(Uint16 x)
    62 	__asm__("xchgb %b0,%h0" : "=q" (x) :  "0" (x));
    68 {
    63 	return x;
    69   __asm__("xchgb %b0,%h0": "=q"(x):"0"(x));
       
    70     return x;
    64 }
    71 }
    65 #elif defined(__GNUC__) && defined(__x86_64__)
    72 #elif defined(__GNUC__) && defined(__x86_64__)
    66 static __inline__ Uint16 SDL_Swap16(Uint16 x)
    73 static __inline__ Uint16
    67 {
    74 SDL_Swap16(Uint16 x)
    68 	__asm__("xchgb %b0,%h0" : "=Q" (x) :  "0" (x));
    75 {
    69 	return x;
    76   __asm__("xchgb %b0,%h0": "=Q"(x):"0"(x));
       
    77     return x;
    70 }
    78 }
    71 #elif defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__))
    79 #elif defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__))
    72 static __inline__ Uint16 SDL_Swap16(Uint16 x)
    80 static __inline__ Uint16
    73 {
    81 SDL_Swap16(Uint16 x)
    74 	Uint16 result;
    82 {
    75 
    83     Uint16 result;
    76 	__asm__("rlwimi %0,%2,8,16,23" : "=&r" (result) : "0" (x >> 8), "r" (x));
    84 
    77 	return result;
    85   __asm__("rlwimi %0,%2,8,16,23": "=&r"(result):"0"(x >> 8), "r"(x));
       
    86     return result;
    78 }
    87 }
    79 #elif defined(__GNUC__) && (defined(__M68000__) || defined(__M68020__))
    88 #elif defined(__GNUC__) && (defined(__M68000__) || defined(__M68020__))
    80 static __inline__ Uint16 SDL_Swap16(Uint16 x)
    89 static __inline__ Uint16
    81 {
    90 SDL_Swap16(Uint16 x)
    82 	__asm__("rorw #8,%0" : "=d" (x) :  "0" (x) : "cc");
    91 {
    83 	return x;
    92   __asm__("rorw #8,%0": "=d"(x): "0"(x):"cc");
    84 }
    93     return x;
    85 #else
    94 }
    86 static __inline__ Uint16 SDL_Swap16(Uint16 x) {
    95 #else
    87 	return((x<<8)|(x>>8));
    96 static __inline__ Uint16
       
    97 SDL_Swap16(Uint16 x)
       
    98 {
       
    99     return ((x << 8) | (x >> 8));
    88 }
   100 }
    89 #endif
   101 #endif
    90 
   102 
    91 #if defined(__GNUC__) && defined(__i386__)
   103 #if defined(__GNUC__) && defined(__i386__)
    92 static __inline__ Uint32 SDL_Swap32(Uint32 x)
   104 static __inline__ Uint32
    93 {
   105 SDL_Swap32(Uint32 x)
    94 	__asm__("bswap %0" : "=r" (x) : "0" (x));
   106 {
    95 	return x;
   107   __asm__("bswap %0": "=r"(x):"0"(x));
       
   108     return x;
    96 }
   109 }
    97 #elif defined(__GNUC__) && defined(__x86_64__)
   110 #elif defined(__GNUC__) && defined(__x86_64__)
    98 static __inline__ Uint32 SDL_Swap32(Uint32 x)
   111 static __inline__ Uint32
    99 {
   112 SDL_Swap32(Uint32 x)
   100 	__asm__("bswapl %0" : "=r" (x) : "0" (x));
   113 {
   101 	return x;
   114   __asm__("bswapl %0": "=r"(x):"0"(x));
       
   115     return x;
   102 }
   116 }
   103 #elif defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__))
   117 #elif defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__))
   104 static __inline__ Uint32 SDL_Swap32(Uint32 x)
   118 static __inline__ Uint32
   105 {
   119 SDL_Swap32(Uint32 x)
   106 	Uint32 result;
   120 {
   107 
   121     Uint32 result;
   108 	__asm__("rlwimi %0,%2,24,16,23" : "=&r" (result) : "0" (x>>24), "r" (x));
   122 
   109 	__asm__("rlwimi %0,%2,8,8,15"   : "=&r" (result) : "0" (result),    "r" (x));
   123   __asm__("rlwimi %0,%2,24,16,23": "=&r"(result):"0"(x >> 24), "r"(x));
   110 	__asm__("rlwimi %0,%2,24,0,7"   : "=&r" (result) : "0" (result),    "r" (x));
   124   __asm__("rlwimi %0,%2,8,8,15": "=&r"(result):"0"(result), "r"(x));
   111 	return result;
   125   __asm__("rlwimi %0,%2,24,0,7": "=&r"(result):"0"(result), "r"(x));
       
   126     return result;
   112 }
   127 }
   113 #elif defined(__GNUC__) && (defined(__M68000__) || defined(__M68020__))
   128 #elif defined(__GNUC__) && (defined(__M68000__) || defined(__M68020__))
   114 static __inline__ Uint32 SDL_Swap32(Uint32 x)
   129 static __inline__ Uint32
   115 {
   130 SDL_Swap32(Uint32 x)
   116 	__asm__("rorw #8,%0\n\tswap %0\n\trorw #8,%0" : "=d" (x) :  "0" (x) : "cc");
   131 {
   117 	return x;
   132   __asm__("rorw #8,%0\n\tswap %0\n\trorw #8,%0": "=d"(x): "0"(x):"cc");
   118 }
   133     return x;
   119 #else
   134 }
   120 static __inline__ Uint32 SDL_Swap32(Uint32 x) {
   135 #else
   121 	return((x<<24)|((x<<8)&0x00FF0000)|((x>>8)&0x0000FF00)|(x>>24));
   136 static __inline__ Uint32
       
   137 SDL_Swap32(Uint32 x)
       
   138 {
       
   139     return ((x << 24) | ((x << 8) & 0x00FF0000) | ((x >> 8) & 0x0000FF00) |
       
   140             (x >> 24));
   122 }
   141 }
   123 #endif
   142 #endif
   124 
   143 
   125 #ifdef SDL_HAS_64BIT_TYPE
   144 #ifdef SDL_HAS_64BIT_TYPE
   126 #if defined(__GNUC__) && defined(__i386__)
   145 #if defined(__GNUC__) && defined(__i386__)
   127 static __inline__ Uint64 SDL_Swap64(Uint64 x)
   146 static __inline__ Uint64
   128 {
   147 SDL_Swap64(Uint64 x)
   129 	union { 
   148 {
   130 		struct { Uint32 a,b; } s;
   149     union
   131 		Uint64 u;
   150     {
   132 	} v;
   151         struct
   133 	v.u = x;
   152         {
   134 	__asm__("bswapl %0 ; bswapl %1 ; xchgl %0,%1" 
   153             Uint32 a, b;
   135 	        : "=r" (v.s.a), "=r" (v.s.b) 
   154         } s;
   136 	        : "0" (v.s.a), "1" (v.s.b)); 
   155         Uint64 u;
   137 	return v.u;
   156     } v;
       
   157     v.u = x;
       
   158   __asm__("bswapl %0 ; bswapl %1 ; xchgl %0,%1": "=r"(v.s.a), "=r"(v.s.b):"0"(v.s.a),
       
   159             "1"(v.s.
       
   160                 b));
       
   161     return v.u;
   138 }
   162 }
   139 #elif defined(__GNUC__) && defined(__x86_64__)
   163 #elif defined(__GNUC__) && defined(__x86_64__)
   140 static __inline__ Uint64 SDL_Swap64(Uint64 x)
   164 static __inline__ Uint64
   141 {
   165 SDL_Swap64(Uint64 x)
   142 	__asm__("bswapq %0" : "=r" (x) : "0" (x));
   166 {
   143 	return x;
   167   __asm__("bswapq %0": "=r"(x):"0"(x));
   144 }
   168     return x;
   145 #else
   169 }
   146 static __inline__ Uint64 SDL_Swap64(Uint64 x)
   170 #else
   147 {
   171 static __inline__ Uint64
   148 	Uint32 hi, lo;
   172 SDL_Swap64(Uint64 x)
   149 
   173 {
   150 	/* Separate into high and low 32-bit values and swap them */
   174     Uint32 hi, lo;
   151 	lo = (Uint32)(x&0xFFFFFFFF);
   175 
   152 	x >>= 32;
   176     /* Separate into high and low 32-bit values and swap them */
   153 	hi = (Uint32)(x&0xFFFFFFFF);
   177     lo = (Uint32) (x & 0xFFFFFFFF);
   154 	x = SDL_Swap32(lo);
   178     x >>= 32;
   155 	x <<= 32;
   179     hi = (Uint32) (x & 0xFFFFFFFF);
   156 	x |= SDL_Swap32(hi);
   180     x = SDL_Swap32(lo);
   157 	return(x);
   181     x <<= 32;
       
   182     x |= SDL_Swap32(hi);
       
   183     return (x);
   158 }
   184 }
   159 #endif
   185 #endif
   160 #else
   186 #else
   161 /* This is mainly to keep compilers from complaining in SDL code.
   187 /* This is mainly to keep compilers from complaining in SDL code.
   162    If there is no real 64-bit datatype, then compilers will complain about
   188    If there is no real 64-bit datatype, then compilers will complain about
   183 #define SDL_SwapBE64(X)	(X)
   209 #define SDL_SwapBE64(X)	(X)
   184 #endif
   210 #endif
   185 
   211 
   186 /* Ends C function definitions when using C++ */
   212 /* Ends C function definitions when using C++ */
   187 #ifdef __cplusplus
   213 #ifdef __cplusplus
   188 }
   214 /* *INDENT-OFF* */
       
   215 }
       
   216 /* *INDENT-ON* */
   189 #endif
   217 #endif
   190 #include "close_code.h"
   218 #include "close_code.h"
   191 
   219 
   192 #endif /* _SDL_endian_h */
   220 #endif /* _SDL_endian_h */
       
   221 
       
   222 /* vi: set ts=4 sw=4 expandtab: */