include/SDL_endian.h
author David Ludwig <dludwig@pobox.com>
Mon, 01 Apr 2013 21:33:06 -0400
changeset 8453 499aa167ea79
parent 6885 700f1b25f77f
child 7004 18d4df6942c2
permissions -rw-r--r--
WinRT: made WinRT path retrieval be available in both UCS-2 and UTF-8 flavors
     1 /*
     2   Simple DirectMedia Layer
     3   Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
     4 
     5   This software is provided 'as-is', without any express or implied
     6   warranty.  In no event will the authors be held liable for any damages
     7   arising from the use of this software.
     8 
     9   Permission is granted to anyone to use this software for any purpose,
    10   including commercial applications, and to alter it and redistribute it
    11   freely, subject to the following restrictions:
    12 
    13   1. The origin of this software must not be misrepresented; you must not
    14      claim that you wrote the original software. If you use this software
    15      in a product, an acknowledgment in the product documentation would be
    16      appreciated but is not required.
    17   2. Altered source versions must be plainly marked as such, and must not be
    18      misrepresented as being the original software.
    19   3. This notice may not be removed or altered from any source distribution.
    20 */
    21 
    22 /**
    23  *  \file SDL_endian.h
    24  *  
    25  *  Functions for reading and writing endian-specific values
    26  */
    27 
    28 #ifndef _SDL_endian_h
    29 #define _SDL_endian_h
    30 
    31 #include "SDL_stdinc.h"
    32 
    33 /**
    34  *  \name The two types of endianness
    35  */
    36 /*@{*/
    37 #define SDL_LIL_ENDIAN	1234
    38 #define SDL_BIG_ENDIAN	4321
    39 /*@}*/
    40 
    41 #ifndef SDL_BYTEORDER           /* Not defined in SDL_config.h? */
    42 #ifdef __linux__
    43 #include <endian.h>
    44 #define SDL_BYTEORDER  __BYTE_ORDER
    45 #else /* __linux __ */
    46 #if defined(__hppa__) || \
    47     defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || \
    48     (defined(__MIPS__) && defined(__MISPEB__)) || \
    49     defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC) || \
    50     defined(__sparc__)
    51 #define SDL_BYTEORDER	SDL_BIG_ENDIAN
    52 #else
    53 #define SDL_BYTEORDER	SDL_LIL_ENDIAN
    54 #endif
    55 #endif /* __linux __ */
    56 #endif /* !SDL_BYTEORDER */
    57 
    58 
    59 #include "begin_code.h"
    60 /* Set up for C function definitions, even when using C++ */
    61 #ifdef __cplusplus
    62 /* *INDENT-OFF* */
    63 extern "C" {
    64 /* *INDENT-ON* */
    65 #endif
    66 
    67 /**
    68  *  \file SDL_endian.h
    69  *  
    70  *  Uses inline functions for compilers that support them, and static
    71  *  functions for those that do not.  Because these functions become
    72  *  static for compilers that do not support inline functions, this
    73  *  header should only be included in files that actually use them.
    74  */
    75 #if defined(__GNUC__) && defined(__i386__) && \
    76    !(__GNUC__ == 2 && __GNUC_MINOR__ == 95 /* broken gcc version */)
    77 static __inline__ Uint16
    78 SDL_Swap16(Uint16 x)
    79 {
    80   __asm__("xchgb %b0,%h0": "=q"(x):"0"(x));
    81     return x;
    82 }
    83 #elif defined(__GNUC__) && defined(__x86_64__)
    84 static __inline__ Uint16
    85 SDL_Swap16(Uint16 x)
    86 {
    87   __asm__("xchgb %b0,%h0": "=Q"(x):"0"(x));
    88     return x;
    89 }
    90 #elif defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__))
    91 static __inline__ Uint16
    92 SDL_Swap16(Uint16 x)
    93 {
    94     int result;
    95 
    96   __asm__("rlwimi %0,%2,8,16,23": "=&r"(result):"0"(x >> 8), "r"(x));
    97     return (Uint16)result;
    98 }
    99 #elif defined(__GNUC__) && (defined(__M68000__) || defined(__M68020__)) && !defined(__mcoldfire__)
   100 static __inline__ Uint16
   101 SDL_Swap16(Uint16 x)
   102 {
   103   __asm__("rorw #8,%0": "=d"(x): "0"(x):"cc");
   104     return x;
   105 }
   106 #else
   107 static __inline__ Uint16
   108 SDL_Swap16(Uint16 x)
   109 {
   110     return SDL_static_cast(Uint16, ((x << 8) | (x >> 8)));
   111 }
   112 #endif
   113 
   114 #if defined(__GNUC__) && defined(__i386__)
   115 static __inline__ Uint32
   116 SDL_Swap32(Uint32 x)
   117 {
   118   __asm__("bswap %0": "=r"(x):"0"(x));
   119     return x;
   120 }
   121 #elif defined(__GNUC__) && defined(__x86_64__)
   122 static __inline__ Uint32
   123 SDL_Swap32(Uint32 x)
   124 {
   125   __asm__("bswapl %0": "=r"(x):"0"(x));
   126     return x;
   127 }
   128 #elif defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__))
   129 static __inline__ Uint32
   130 SDL_Swap32(Uint32 x)
   131 {
   132     Uint32 result;
   133 
   134   __asm__("rlwimi %0,%2,24,16,23": "=&r"(result):"0"(x >> 24), "r"(x));
   135   __asm__("rlwimi %0,%2,8,8,15": "=&r"(result):"0"(result), "r"(x));
   136   __asm__("rlwimi %0,%2,24,0,7": "=&r"(result):"0"(result), "r"(x));
   137     return result;
   138 }
   139 #elif defined(__GNUC__) && (defined(__M68000__) || defined(__M68020__)) && !defined(__mcoldfire__)
   140 static __inline__ Uint32
   141 SDL_Swap32(Uint32 x)
   142 {
   143   __asm__("rorw #8,%0\n\tswap %0\n\trorw #8,%0": "=d"(x): "0"(x):"cc");
   144     return x;
   145 }
   146 #else
   147 static __inline__ Uint32
   148 SDL_Swap32(Uint32 x)
   149 {
   150     return SDL_static_cast(Uint32, ((x << 24) | ((x << 8) & 0x00FF0000) |
   151                                     ((x >> 8) & 0x0000FF00) | (x >> 24)));
   152 }
   153 #endif
   154 
   155 #if defined(__GNUC__) && defined(__i386__)
   156 static __inline__ Uint64
   157 SDL_Swap64(Uint64 x)
   158 {
   159     union
   160     {
   161         struct
   162         {
   163             Uint32 a, b;
   164         } s;
   165         Uint64 u;
   166     } v;
   167     v.u = x;
   168   __asm__("bswapl %0 ; bswapl %1 ; xchgl %0,%1": "=r"(v.s.a), "=r"(v.s.b):"0"(v.s.a),
   169             "1"(v.s.
   170                 b));
   171     return v.u;
   172 }
   173 #elif defined(__GNUC__) && defined(__x86_64__)
   174 static __inline__ Uint64
   175 SDL_Swap64(Uint64 x)
   176 {
   177   __asm__("bswapq %0": "=r"(x):"0"(x));
   178     return x;
   179 }
   180 #else
   181 static __inline__ Uint64
   182 SDL_Swap64(Uint64 x)
   183 {
   184     Uint32 hi, lo;
   185 
   186     /* Separate into high and low 32-bit values and swap them */
   187     lo = SDL_static_cast(Uint32, x & 0xFFFFFFFF);
   188     x >>= 32;
   189     hi = SDL_static_cast(Uint32, x & 0xFFFFFFFF);
   190     x = SDL_Swap32(lo);
   191     x <<= 32;
   192     x |= SDL_Swap32(hi);
   193     return (x);
   194 }
   195 #endif
   196 
   197 
   198 static __inline__ float
   199 SDL_SwapFloat(float x)
   200 {
   201     union
   202     {
   203         float f;
   204         Uint32 ui32;
   205     } swapper;
   206     swapper.f = x;
   207     swapper.ui32 = SDL_Swap32(swapper.ui32);
   208     return swapper.f;
   209 }
   210 
   211 
   212 /**
   213  *  \name Swap to native
   214  *  Byteswap item from the specified endianness to the native endianness.
   215  */
   216 /*@{*/
   217 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
   218 #define SDL_SwapLE16(X)	(X)
   219 #define SDL_SwapLE32(X)	(X)
   220 #define SDL_SwapLE64(X)	(X)
   221 #define SDL_SwapFloatLE(X)	(X)
   222 #define SDL_SwapBE16(X)	SDL_Swap16(X)
   223 #define SDL_SwapBE32(X)	SDL_Swap32(X)
   224 #define SDL_SwapBE64(X)	SDL_Swap64(X)
   225 #define SDL_SwapFloatBE(X)	SDL_SwapFloat(X)
   226 #else
   227 #define SDL_SwapLE16(X)	SDL_Swap16(X)
   228 #define SDL_SwapLE32(X)	SDL_Swap32(X)
   229 #define SDL_SwapLE64(X)	SDL_Swap64(X)
   230 #define SDL_SwapFloatLE(X)	SDL_SwapFloat(X)
   231 #define SDL_SwapBE16(X)	(X)
   232 #define SDL_SwapBE32(X)	(X)
   233 #define SDL_SwapBE64(X)	(X)
   234 #define SDL_SwapFloatBE(X)	(X)
   235 #endif
   236 /*@}*//*Swap to native*/
   237 
   238 /* Ends C function definitions when using C++ */
   239 #ifdef __cplusplus
   240 /* *INDENT-OFF* */
   241 }
   242 /* *INDENT-ON* */
   243 #endif
   244 #include "close_code.h"
   245 
   246 #endif /* _SDL_endian_h */
   247 
   248 /* vi: set ts=4 sw=4 expandtab: */