1 | /* |
---|
2 | SDL - Simple DirectMedia Layer |
---|
3 | Copyright (C) 1997-2012 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 | * 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 | /** @name SDL_ENDIANs |
---|
34 | * 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 | extern "C" { |
---|
63 | #endif |
---|
64 | |
---|
65 | /** |
---|
66 | * @name SDL_Swap Functions |
---|
67 | * Use inline functions for compilers that support them, and static |
---|
68 | * functions for those that do not. Because these functions become |
---|
69 | * static for compilers that do not support inline functions, this |
---|
70 | * header should only be included in files that actually use them. |
---|
71 | */ |
---|
72 | /*@{*/ |
---|
73 | #if defined(__GNUC__) && defined(__i386__) && \ |
---|
74 | !(__GNUC__ == 2 && __GNUC_MINOR__ <= 95 /* broken gcc version */) |
---|
75 | static __inline__ Uint16 SDL_Swap16(Uint16 x) |
---|
76 | { |
---|
77 | __asm__("xchgb %b0,%h0" : "=q" (x) : "0" (x)); |
---|
78 | return x; |
---|
79 | } |
---|
80 | #elif defined(__GNUC__) && defined(__x86_64__) |
---|
81 | static __inline__ Uint16 SDL_Swap16(Uint16 x) |
---|
82 | { |
---|
83 | __asm__("xchgb %b0,%h0" : "=Q" (x) : "0" (x)); |
---|
84 | return x; |
---|
85 | } |
---|
86 | #elif defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__)) |
---|
87 | static __inline__ Uint16 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(__m68k__) && !defined(__mcoldfire__)) |
---|
95 | static __inline__ Uint16 SDL_Swap16(Uint16 x) |
---|
96 | { |
---|
97 | __asm__("rorw #8,%0" : "=d" (x) : "0" (x) : "cc"); |
---|
98 | return x; |
---|
99 | } |
---|
100 | #else |
---|
101 | static __inline__ Uint16 SDL_Swap16(Uint16 x) { |
---|
102 | return SDL_static_cast(Uint16, ((x<<8)|(x>>8))); |
---|
103 | } |
---|
104 | #endif |
---|
105 | |
---|
106 | #if defined(__GNUC__) && defined(__i386__) && \ |
---|
107 | !(__GNUC__ == 2 && __GNUC_MINOR__ <= 95 /* broken gcc version */) |
---|
108 | static __inline__ Uint32 SDL_Swap32(Uint32 x) |
---|
109 | { |
---|
110 | __asm__("bswap %0" : "=r" (x) : "0" (x)); |
---|
111 | return x; |
---|
112 | } |
---|
113 | #elif defined(__GNUC__) && defined(__x86_64__) |
---|
114 | static __inline__ Uint32 SDL_Swap32(Uint32 x) |
---|
115 | { |
---|
116 | __asm__("bswapl %0" : "=r" (x) : "0" (x)); |
---|
117 | return x; |
---|
118 | } |
---|
119 | #elif defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__)) |
---|
120 | static __inline__ Uint32 SDL_Swap32(Uint32 x) |
---|
121 | { |
---|
122 | Uint32 result; |
---|
123 | |
---|
124 | __asm__("rlwimi %0,%2,24,16,23" : "=&r" (result) : "0" (x>>24), "r" (x)); |
---|
125 | __asm__("rlwimi %0,%2,8,8,15" : "=&r" (result) : "0" (result), "r" (x)); |
---|
126 | __asm__("rlwimi %0,%2,24,0,7" : "=&r" (result) : "0" (result), "r" (x)); |
---|
127 | return result; |
---|
128 | } |
---|
129 | #elif defined(__GNUC__) && (defined(__m68k__) && !defined(__mcoldfire__)) |
---|
130 | static __inline__ Uint32 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 SDL_Swap32(Uint32 x) { |
---|
137 | return SDL_static_cast(Uint32, ((x<<24)|((x<<8)&0x00FF0000)|((x>>8)&0x0000FF00)|(x>>24))); |
---|
138 | } |
---|
139 | #endif |
---|
140 | |
---|
141 | #ifdef SDL_HAS_64BIT_TYPE |
---|
142 | #if defined(__GNUC__) && defined(__i386__) && \ |
---|
143 | !(__GNUC__ == 2 && __GNUC_MINOR__ <= 95 /* broken gcc version */) |
---|
144 | static __inline__ Uint64 SDL_Swap64(Uint64 x) |
---|
145 | { |
---|
146 | union { |
---|
147 | struct { Uint32 a,b; } s; |
---|
148 | Uint64 u; |
---|
149 | } v; |
---|
150 | v.u = x; |
---|
151 | __asm__("bswapl %0 ; bswapl %1 ; xchgl %0,%1" |
---|
152 | : "=r" (v.s.a), "=r" (v.s.b) |
---|
153 | : "0" (v.s.a), "1" (v.s.b)); |
---|
154 | return v.u; |
---|
155 | } |
---|
156 | #elif defined(__GNUC__) && defined(__x86_64__) |
---|
157 | static __inline__ Uint64 SDL_Swap64(Uint64 x) |
---|
158 | { |
---|
159 | __asm__("bswapq %0" : "=r" (x) : "0" (x)); |
---|
160 | return x; |
---|
161 | } |
---|
162 | #else |
---|
163 | static __inline__ Uint64 SDL_Swap64(Uint64 x) |
---|
164 | { |
---|
165 | Uint32 hi, lo; |
---|
166 | |
---|
167 | /* Separate into high and low 32-bit values and swap them */ |
---|
168 | lo = SDL_static_cast(Uint32, x & 0xFFFFFFFF); |
---|
169 | x >>= 32; |
---|
170 | hi = SDL_static_cast(Uint32, x & 0xFFFFFFFF); |
---|
171 | x = SDL_Swap32(lo); |
---|
172 | x <<= 32; |
---|
173 | x |= SDL_Swap32(hi); |
---|
174 | return (x); |
---|
175 | } |
---|
176 | #endif |
---|
177 | #else |
---|
178 | /* This is mainly to keep compilers from complaining in SDL code. |
---|
179 | * If there is no real 64-bit datatype, then compilers will complain about |
---|
180 | * the fake 64-bit datatype that SDL provides when it compiles user code. |
---|
181 | */ |
---|
182 | #define SDL_Swap64(X) (X) |
---|
183 | #endif /* SDL_HAS_64BIT_TYPE */ |
---|
184 | /*@}*/ |
---|
185 | |
---|
186 | /** |
---|
187 | * @name SDL_SwapLE and SDL_SwapBE Functions |
---|
188 | * Byteswap item from the specified endianness to the native endianness |
---|
189 | */ |
---|
190 | /*@{*/ |
---|
191 | #if SDL_BYTEORDER == SDL_LIL_ENDIAN |
---|
192 | #define SDL_SwapLE16(X) (X) |
---|
193 | #define SDL_SwapLE32(X) (X) |
---|
194 | #define SDL_SwapLE64(X) (X) |
---|
195 | #define SDL_SwapBE16(X) SDL_Swap16(X) |
---|
196 | #define SDL_SwapBE32(X) SDL_Swap32(X) |
---|
197 | #define SDL_SwapBE64(X) SDL_Swap64(X) |
---|
198 | #else |
---|
199 | #define SDL_SwapLE16(X) SDL_Swap16(X) |
---|
200 | #define SDL_SwapLE32(X) SDL_Swap32(X) |
---|
201 | #define SDL_SwapLE64(X) SDL_Swap64(X) |
---|
202 | #define SDL_SwapBE16(X) (X) |
---|
203 | #define SDL_SwapBE32(X) (X) |
---|
204 | #define SDL_SwapBE64(X) (X) |
---|
205 | #endif |
---|
206 | /*@}*/ |
---|
207 | |
---|
208 | /* Ends C function definitions when using C++ */ |
---|
209 | #ifdef __cplusplus |
---|
210 | } |
---|
211 | #endif |
---|
212 | #include "close_code.h" |
---|
213 | |
---|
214 | #endif /* _SDL_endian_h */ |
---|