include/SDL_endian.h
author Ryan C. Gordon <icculus@icculus.org>
Fri, 15 Mar 2013 01:09:19 -0400
changeset 7004 18d4df6942c2
parent 6885 700f1b25f77f
child 7191 75360622e65f
permissions -rw-r--r--
Replace all the "static __inline__" functions with SDL_FORCE_INLINE.
     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 #if defined(__GNUC__) && defined(__i386__) && \
    71    !(__GNUC__ == 2 && __GNUC_MINOR__ == 95 /* broken gcc version */)
    72 SDL_FORCE_INLINE Uint16
    73 SDL_Swap16(Uint16 x)
    74 {
    75   __asm__("xchgb %b0,%h0": "=q"(x):"0"(x));
    76     return x;
    77 }
    78 #elif defined(__GNUC__) && defined(__x86_64__)
    79 SDL_FORCE_INLINE Uint16
    80 SDL_Swap16(Uint16 x)
    81 {
    82   __asm__("xchgb %b0,%h0": "=Q"(x):"0"(x));
    83     return x;
    84 }
    85 #elif defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__))
    86 SDL_FORCE_INLINE Uint16
    87 SDL_Swap16(Uint16 x)
    88 {
    89     int result;
    90 
    91   __asm__("rlwimi %0,%2,8,16,23": "=&r"(result):"0"(x >> 8), "r"(x));
    92     return (Uint16)result;
    93 }
    94 #elif defined(__GNUC__) && (defined(__M68000__) || defined(__M68020__)) && !defined(__mcoldfire__)
    95 SDL_FORCE_INLINE Uint16
    96 SDL_Swap16(Uint16 x)
    97 {
    98   __asm__("rorw #8,%0": "=d"(x): "0"(x):"cc");
    99     return x;
   100 }
   101 #else
   102 SDL_FORCE_INLINE Uint16
   103 SDL_Swap16(Uint16 x)
   104 {
   105     return SDL_static_cast(Uint16, ((x << 8) | (x >> 8)));
   106 }
   107 #endif
   108 
   109 #if defined(__GNUC__) && defined(__i386__)
   110 SDL_FORCE_INLINE Uint32
   111 SDL_Swap32(Uint32 x)
   112 {
   113   __asm__("bswap %0": "=r"(x):"0"(x));
   114     return x;
   115 }
   116 #elif defined(__GNUC__) && defined(__x86_64__)
   117 SDL_FORCE_INLINE Uint32
   118 SDL_Swap32(Uint32 x)
   119 {
   120   __asm__("bswapl %0": "=r"(x):"0"(x));
   121     return x;
   122 }
   123 #elif defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__))
   124 SDL_FORCE_INLINE Uint32
   125 SDL_Swap32(Uint32 x)
   126 {
   127     Uint32 result;
   128 
   129   __asm__("rlwimi %0,%2,24,16,23": "=&r"(result):"0"(x >> 24), "r"(x));
   130   __asm__("rlwimi %0,%2,8,8,15": "=&r"(result):"0"(result), "r"(x));
   131   __asm__("rlwimi %0,%2,24,0,7": "=&r"(result):"0"(result), "r"(x));
   132     return result;
   133 }
   134 #elif defined(__GNUC__) && (defined(__M68000__) || defined(__M68020__)) && !defined(__mcoldfire__)
   135 SDL_FORCE_INLINE Uint32
   136 SDL_Swap32(Uint32 x)
   137 {
   138   __asm__("rorw #8,%0\n\tswap %0\n\trorw #8,%0": "=d"(x): "0"(x):"cc");
   139     return x;
   140 }
   141 #else
   142 SDL_FORCE_INLINE Uint32
   143 SDL_Swap32(Uint32 x)
   144 {
   145     return SDL_static_cast(Uint32, ((x << 24) | ((x << 8) & 0x00FF0000) |
   146                                     ((x >> 8) & 0x0000FF00) | (x >> 24)));
   147 }
   148 #endif
   149 
   150 #if defined(__GNUC__) && defined(__i386__)
   151 SDL_FORCE_INLINE Uint64
   152 SDL_Swap64(Uint64 x)
   153 {
   154     union
   155     {
   156         struct
   157         {
   158             Uint32 a, b;
   159         } s;
   160         Uint64 u;
   161     } v;
   162     v.u = x;
   163   __asm__("bswapl %0 ; bswapl %1 ; xchgl %0,%1": "=r"(v.s.a), "=r"(v.s.b):"0"(v.s.a),
   164             "1"(v.s.
   165                 b));
   166     return v.u;
   167 }
   168 #elif defined(__GNUC__) && defined(__x86_64__)
   169 SDL_FORCE_INLINE Uint64
   170 SDL_Swap64(Uint64 x)
   171 {
   172   __asm__("bswapq %0": "=r"(x):"0"(x));
   173     return x;
   174 }
   175 #else
   176 SDL_FORCE_INLINE Uint64
   177 SDL_Swap64(Uint64 x)
   178 {
   179     Uint32 hi, lo;
   180 
   181     /* Separate into high and low 32-bit values and swap them */
   182     lo = SDL_static_cast(Uint32, x & 0xFFFFFFFF);
   183     x >>= 32;
   184     hi = SDL_static_cast(Uint32, x & 0xFFFFFFFF);
   185     x = SDL_Swap32(lo);
   186     x <<= 32;
   187     x |= SDL_Swap32(hi);
   188     return (x);
   189 }
   190 #endif
   191 
   192 
   193 SDL_FORCE_INLINE float
   194 SDL_SwapFloat(float x)
   195 {
   196     union
   197     {
   198         float f;
   199         Uint32 ui32;
   200     } swapper;
   201     swapper.f = x;
   202     swapper.ui32 = SDL_Swap32(swapper.ui32);
   203     return swapper.f;
   204 }
   205 
   206 
   207 /**
   208  *  \name Swap to native
   209  *  Byteswap item from the specified endianness to the native endianness.
   210  */
   211 /*@{*/
   212 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
   213 #define SDL_SwapLE16(X)	(X)
   214 #define SDL_SwapLE32(X)	(X)
   215 #define SDL_SwapLE64(X)	(X)
   216 #define SDL_SwapFloatLE(X)	(X)
   217 #define SDL_SwapBE16(X)	SDL_Swap16(X)
   218 #define SDL_SwapBE32(X)	SDL_Swap32(X)
   219 #define SDL_SwapBE64(X)	SDL_Swap64(X)
   220 #define SDL_SwapFloatBE(X)	SDL_SwapFloat(X)
   221 #else
   222 #define SDL_SwapLE16(X)	SDL_Swap16(X)
   223 #define SDL_SwapLE32(X)	SDL_Swap32(X)
   224 #define SDL_SwapLE64(X)	SDL_Swap64(X)
   225 #define SDL_SwapFloatLE(X)	SDL_SwapFloat(X)
   226 #define SDL_SwapBE16(X)	(X)
   227 #define SDL_SwapBE32(X)	(X)
   228 #define SDL_SwapBE64(X)	(X)
   229 #define SDL_SwapFloatBE(X)	(X)
   230 #endif
   231 /*@}*//*Swap to native*/
   232 
   233 /* Ends C function definitions when using C++ */
   234 #ifdef __cplusplus
   235 /* *INDENT-OFF* */
   236 }
   237 /* *INDENT-ON* */
   238 #endif
   239 #include "close_code.h"
   240 
   241 #endif /* _SDL_endian_h */
   242 
   243 /* vi: set ts=4 sw=4 expandtab: */