Rev 1 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1 | pmbaty | 1 | /* |
2 | Simple DirectMedia Layer |
||
8 | pmbaty | 3 | Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> |
1 | pmbaty | 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 | extern "C" { |
||
63 | #endif |
||
64 | |||
65 | /** |
||
66 | * \file SDL_endian.h |
||
67 | */ |
||
68 | #if defined(__GNUC__) && defined(__i386__) && \ |
||
69 | !(__GNUC__ == 2 && __GNUC_MINOR__ == 95 /* broken gcc version */) |
||
70 | SDL_FORCE_INLINE Uint16 |
||
71 | SDL_Swap16(Uint16 x) |
||
72 | { |
||
73 | __asm__("xchgb %b0,%h0": "=q"(x):"0"(x)); |
||
74 | return x; |
||
75 | } |
||
76 | #elif defined(__GNUC__) && defined(__x86_64__) |
||
77 | SDL_FORCE_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(__powerpc__) || defined(__ppc__)) |
||
84 | SDL_FORCE_INLINE Uint16 |
||
85 | SDL_Swap16(Uint16 x) |
||
86 | { |
||
87 | int result; |
||
88 | |||
89 | __asm__("rlwimi %0,%2,8,16,23": "=&r"(result):"0"(x >> 8), "r"(x)); |
||
90 | return (Uint16)result; |
||
91 | } |
||
92 | #elif defined(__GNUC__) && (defined(__M68000__) || defined(__M68020__)) && !defined(__mcoldfire__) |
||
93 | SDL_FORCE_INLINE Uint16 |
||
94 | SDL_Swap16(Uint16 x) |
||
95 | { |
||
96 | __asm__("rorw #8,%0": "=d"(x): "0"(x):"cc"); |
||
97 | return x; |
||
98 | } |
||
99 | #elif defined(__WATCOMC__) && defined(__386__) |
||
100 | extern _inline Uint16 SDL_Swap16(Uint16); |
||
101 | #pragma aux SDL_Swap16 = \ |
||
102 | "xchg al, ah" \ |
||
103 | parm [ax] \ |
||
104 | modify [ax]; |
||
105 | #else |
||
106 | SDL_FORCE_INLINE Uint16 |
||
107 | SDL_Swap16(Uint16 x) |
||
108 | { |
||
109 | return SDL_static_cast(Uint16, ((x << 8) | (x >> 8))); |
||
110 | } |
||
111 | #endif |
||
112 | |||
113 | #if defined(__GNUC__) && defined(__i386__) |
||
114 | SDL_FORCE_INLINE Uint32 |
||
115 | SDL_Swap32(Uint32 x) |
||
116 | { |
||
117 | __asm__("bswap %0": "=r"(x):"0"(x)); |
||
118 | return x; |
||
119 | } |
||
120 | #elif defined(__GNUC__) && defined(__x86_64__) |
||
121 | SDL_FORCE_INLINE Uint32 |
||
122 | SDL_Swap32(Uint32 x) |
||
123 | { |
||
124 | __asm__("bswapl %0": "=r"(x):"0"(x)); |
||
125 | return x; |
||
126 | } |
||
127 | #elif defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__)) |
||
128 | SDL_FORCE_INLINE Uint32 |
||
129 | SDL_Swap32(Uint32 x) |
||
130 | { |
||
131 | Uint32 result; |
||
132 | |||
133 | __asm__("rlwimi %0,%2,24,16,23": "=&r"(result):"0"(x >> 24), "r"(x)); |
||
134 | __asm__("rlwimi %0,%2,8,8,15": "=&r"(result):"0"(result), "r"(x)); |
||
135 | __asm__("rlwimi %0,%2,24,0,7": "=&r"(result):"0"(result), "r"(x)); |
||
136 | return result; |
||
137 | } |
||
138 | #elif defined(__GNUC__) && (defined(__M68000__) || defined(__M68020__)) && !defined(__mcoldfire__) |
||
139 | SDL_FORCE_INLINE Uint32 |
||
140 | SDL_Swap32(Uint32 x) |
||
141 | { |
||
142 | __asm__("rorw #8,%0\n\tswap %0\n\trorw #8,%0": "=d"(x): "0"(x):"cc"); |
||
143 | return x; |
||
144 | } |
||
145 | #elif defined(__WATCOMC__) && defined(__386__) |
||
146 | extern _inline Uint32 SDL_Swap32(Uint32); |
||
147 | #ifndef __SW_3 /* 486+ */ |
||
148 | #pragma aux SDL_Swap32 = \ |
||
149 | "bswap eax" \ |
||
150 | parm [eax] \ |
||
151 | modify [eax]; |
||
152 | #else /* 386-only */ |
||
153 | #pragma aux SDL_Swap32 = \ |
||
154 | "xchg al, ah" \ |
||
155 | "ror eax, 16" \ |
||
156 | "xchg al, ah" \ |
||
157 | parm [eax] \ |
||
158 | modify [eax]; |
||
159 | #endif |
||
160 | #else |
||
161 | SDL_FORCE_INLINE Uint32 |
||
162 | SDL_Swap32(Uint32 x) |
||
163 | { |
||
164 | return SDL_static_cast(Uint32, ((x << 24) | ((x << 8) & 0x00FF0000) | |
||
165 | ((x >> 8) & 0x0000FF00) | (x >> 24))); |
||
166 | } |
||
167 | #endif |
||
168 | |||
169 | #if defined(__GNUC__) && defined(__i386__) |
||
170 | SDL_FORCE_INLINE Uint64 |
||
171 | SDL_Swap64(Uint64 x) |
||
172 | { |
||
173 | union |
||
174 | { |
||
175 | struct |
||
176 | { |
||
177 | Uint32 a, b; |
||
178 | } s; |
||
179 | Uint64 u; |
||
180 | } v; |
||
181 | v.u = x; |
||
182 | __asm__("bswapl %0 ; bswapl %1 ; xchgl %0,%1": "=r"(v.s.a), "=r"(v.s.b):"0"(v.s.a), |
||
183 | "1"(v.s. |
||
184 | b)); |
||
185 | return v.u; |
||
186 | } |
||
187 | #elif defined(__GNUC__) && defined(__x86_64__) |
||
188 | SDL_FORCE_INLINE Uint64 |
||
189 | SDL_Swap64(Uint64 x) |
||
190 | { |
||
191 | __asm__("bswapq %0": "=r"(x):"0"(x)); |
||
192 | return x; |
||
193 | } |
||
194 | #else |
||
195 | SDL_FORCE_INLINE Uint64 |
||
196 | SDL_Swap64(Uint64 x) |
||
197 | { |
||
198 | Uint32 hi, lo; |
||
199 | |||
200 | /* Separate into high and low 32-bit values and swap them */ |
||
201 | lo = SDL_static_cast(Uint32, x & 0xFFFFFFFF); |
||
202 | x >>= 32; |
||
203 | hi = SDL_static_cast(Uint32, x & 0xFFFFFFFF); |
||
204 | x = SDL_Swap32(lo); |
||
205 | x <<= 32; |
||
206 | x |= SDL_Swap32(hi); |
||
207 | return (x); |
||
208 | } |
||
209 | #endif |
||
210 | |||
211 | |||
212 | SDL_FORCE_INLINE float |
||
213 | SDL_SwapFloat(float x) |
||
214 | { |
||
215 | union |
||
216 | { |
||
217 | float f; |
||
218 | Uint32 ui32; |
||
219 | } swapper; |
||
220 | swapper.f = x; |
||
221 | swapper.ui32 = SDL_Swap32(swapper.ui32); |
||
222 | return swapper.f; |
||
223 | } |
||
224 | |||
225 | |||
226 | /** |
||
227 | * \name Swap to native |
||
228 | * Byteswap item from the specified endianness to the native endianness. |
||
229 | */ |
||
230 | /* @{ */ |
||
231 | #if SDL_BYTEORDER == SDL_LIL_ENDIAN |
||
232 | #define SDL_SwapLE16(X) (X) |
||
233 | #define SDL_SwapLE32(X) (X) |
||
234 | #define SDL_SwapLE64(X) (X) |
||
235 | #define SDL_SwapFloatLE(X) (X) |
||
236 | #define SDL_SwapBE16(X) SDL_Swap16(X) |
||
237 | #define SDL_SwapBE32(X) SDL_Swap32(X) |
||
238 | #define SDL_SwapBE64(X) SDL_Swap64(X) |
||
239 | #define SDL_SwapFloatBE(X) SDL_SwapFloat(X) |
||
240 | #else |
||
241 | #define SDL_SwapLE16(X) SDL_Swap16(X) |
||
242 | #define SDL_SwapLE32(X) SDL_Swap32(X) |
||
243 | #define SDL_SwapLE64(X) SDL_Swap64(X) |
||
244 | #define SDL_SwapFloatLE(X) SDL_SwapFloat(X) |
||
245 | #define SDL_SwapBE16(X) (X) |
||
246 | #define SDL_SwapBE32(X) (X) |
||
247 | #define SDL_SwapBE64(X) (X) |
||
248 | #define SDL_SwapFloatBE(X) (X) |
||
249 | #endif |
||
250 | /* @} *//* Swap to native */ |
||
251 | |||
252 | /* Ends C function definitions when using C++ */ |
||
253 | #ifdef __cplusplus |
||
254 | } |
||
255 | #endif |
||
256 | #include "close_code.h" |
||
257 | |||
258 | #endif /* SDL_endian_h_ */ |
||
259 | |||
260 | /* vi: set ts=4 sw=4 expandtab: */ |