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