|
1
|
1 /*
|
|
|
2 Simple DirectMedia Layer
|
|
|
3 Copyright (C) 1997-2025 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 * # CategoryEndian
|
|
|
24 *
|
|
|
25 * Functions converting endian-specific values to different byte orders.
|
|
|
26 *
|
|
|
27 * These functions either unconditionally swap byte order (SDL_Swap16,
|
|
|
28 * SDL_Swap32, SDL_Swap64, SDL_SwapFloat), or they swap to/from the system's
|
|
|
29 * native byte order (SDL_Swap16LE, SDL_Swap16BE, SDL_Swap32LE, SDL_Swap32BE,
|
|
|
30 * SDL_Swap32LE, SDL_Swap32BE, SDL_SwapFloatLE, SDL_SwapFloatBE). In the
|
|
|
31 * latter case, the functionality is provided by macros that become no-ops if
|
|
|
32 * a swap isn't necessary: on an x86 (littleendian) processor, SDL_Swap32LE
|
|
|
33 * does nothing, but SDL_Swap32BE reverses the bytes of the data. On a PowerPC
|
|
|
34 * processor (bigendian), the macros behavior is reversed.
|
|
|
35 *
|
|
|
36 * The swap routines are inline functions, and attempt to use compiler
|
|
|
37 * intrinsics, inline assembly, and other magic to make byteswapping
|
|
|
38 * efficient.
|
|
|
39 */
|
|
|
40
|
|
|
41 #ifndef SDL_endian_h_
|
|
|
42 #define SDL_endian_h_
|
|
|
43
|
|
|
44 #include <SDL3/SDL_stdinc.h>
|
|
|
45
|
|
|
46 #if defined(_MSC_VER) && (_MSC_VER >= 1400)
|
|
|
47 /* As of Clang 11, '_m_prefetchw' is conflicting with the winnt.h's version,
|
|
|
48 so we define the needed '_m_prefetch' here as a pseudo-header, until the issue is fixed. */
|
|
|
49 #if defined(__clang__) && !SDL_HAS_BUILTIN(_m_prefetch)
|
|
|
50 #ifndef __PRFCHWINTRIN_H
|
|
|
51 #define __PRFCHWINTRIN_H
|
|
|
52 static __inline__ void __attribute__((__always_inline__, __nodebug__))
|
|
|
53 _m_prefetch(void *__P)
|
|
|
54 {
|
|
|
55 __builtin_prefetch(__P, 0, 3 /* _MM_HINT_T0 */);
|
|
|
56 }
|
|
|
57 #endif /* __PRFCHWINTRIN_H */
|
|
|
58 #endif /* __clang__ */
|
|
|
59
|
|
|
60 #include <intrin.h>
|
|
|
61 #endif
|
|
|
62
|
|
|
63 /**
|
|
|
64 * \name The two types of endianness
|
|
|
65 */
|
|
|
66 /* @{ */
|
|
|
67
|
|
|
68
|
|
|
69 /**
|
|
|
70 * A value to represent littleendian byteorder.
|
|
|
71 *
|
|
|
72 * This is used with the preprocessor macro SDL_BYTEORDER, to determine a
|
|
|
73 * platform's byte ordering:
|
|
|
74 *
|
|
|
75 * ```c
|
|
|
76 * #if SDL_BYTEORDER == SDL_LIL_ENDIAN
|
|
|
77 * SDL_Log("This system is littleendian.");
|
|
|
78 * #endif
|
|
|
79 * ```
|
|
|
80 *
|
|
|
81 * \since This macro is available since SDL 3.2.0.
|
|
|
82 *
|
|
|
83 * \sa SDL_BYTEORDER
|
|
|
84 * \sa SDL_BIG_ENDIAN
|
|
|
85 */
|
|
|
86 #define SDL_LIL_ENDIAN 1234
|
|
|
87
|
|
|
88 /**
|
|
|
89 * A value to represent bigendian byteorder.
|
|
|
90 *
|
|
|
91 * This is used with the preprocessor macro SDL_BYTEORDER, to determine a
|
|
|
92 * platform's byte ordering:
|
|
|
93 *
|
|
|
94 * ```c
|
|
|
95 * #if SDL_BYTEORDER == SDL_BIG_ENDIAN
|
|
|
96 * SDL_Log("This system is bigendian.");
|
|
|
97 * #endif
|
|
|
98 * ```
|
|
|
99 *
|
|
|
100 * \since This macro is available since SDL 3.2.0.
|
|
|
101 *
|
|
|
102 * \sa SDL_BYTEORDER
|
|
|
103 * \sa SDL_LIL_ENDIAN
|
|
|
104 */
|
|
|
105 #define SDL_BIG_ENDIAN 4321
|
|
|
106
|
|
|
107 /* @} */
|
|
|
108
|
|
|
109 #ifndef SDL_BYTEORDER
|
|
|
110 #ifdef SDL_WIKI_DOCUMENTATION_SECTION
|
|
|
111
|
|
|
112 /**
|
|
|
113 * A macro that reports the target system's byte order.
|
|
|
114 *
|
|
|
115 * This is set to either SDL_LIL_ENDIAN or SDL_BIG_ENDIAN (and maybe other
|
|
|
116 * values in the future, if something else becomes popular). This can be
|
|
|
117 * tested with the preprocessor, so decisions can be made at compile time.
|
|
|
118 *
|
|
|
119 * ```c
|
|
|
120 * #if SDL_BYTEORDER == SDL_BIG_ENDIAN
|
|
|
121 * SDL_Log("This system is bigendian.");
|
|
|
122 * #endif
|
|
|
123 * ```
|
|
|
124 *
|
|
|
125 * \since This macro is available since SDL 3.2.0.
|
|
|
126 *
|
|
|
127 * \sa SDL_LIL_ENDIAN
|
|
|
128 * \sa SDL_BIG_ENDIAN
|
|
|
129 */
|
|
|
130 #define SDL_BYTEORDER SDL_LIL_ENDIAN___or_maybe___SDL_BIG_ENDIAN
|
|
|
131 #elif defined(SDL_PLATFORM_LINUX) || defined(__GLIBC__)
|
|
|
132 #include <endian.h>
|
|
|
133 #define SDL_BYTEORDER __BYTE_ORDER
|
|
|
134 #elif defined(SDL_PLATFORM_SOLARIS)
|
|
|
135 #include <sys/byteorder.h>
|
|
|
136 #if defined(_LITTLE_ENDIAN)
|
|
|
137 #define SDL_BYTEORDER SDL_LIL_ENDIAN
|
|
|
138 #elif defined(_BIG_ENDIAN)
|
|
|
139 #define SDL_BYTEORDER SDL_BIG_ENDIAN
|
|
|
140 #else
|
|
|
141 #error Unsupported endianness
|
|
|
142 #endif
|
|
|
143 #elif defined(SDL_PLATFORM_OPENBSD) || defined(__DragonFly__)
|
|
|
144 #include <endian.h>
|
|
|
145 #define SDL_BYTEORDER BYTE_ORDER
|
|
|
146 #elif defined(SDL_PLATFORM_FREEBSD) || defined(SDL_PLATFORM_NETBSD)
|
|
|
147 #include <sys/endian.h>
|
|
|
148 #define SDL_BYTEORDER BYTE_ORDER
|
|
|
149 /* predefs from newer gcc and clang versions: */
|
|
|
150 #elif defined(__ORDER_LITTLE_ENDIAN__) && defined(__ORDER_BIG_ENDIAN__) && defined(__BYTE_ORDER__)
|
|
|
151 #if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
|
|
|
152 #define SDL_BYTEORDER SDL_LIL_ENDIAN
|
|
|
153 #elif (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
|
|
|
154 #define SDL_BYTEORDER SDL_BIG_ENDIAN
|
|
|
155 #else
|
|
|
156 #error Unsupported endianness
|
|
|
157 #endif /**/
|
|
|
158 #else
|
|
|
159 #if defined(__hppa__) || \
|
|
|
160 defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || \
|
|
|
161 (defined(__MIPS__) && defined(__MIPSEB__)) || \
|
|
|
162 defined(__ppc__) || defined(__POWERPC__) || defined(__powerpc__) || defined(__PPC__) || \
|
|
|
163 defined(__sparc__) || defined(__sparc)
|
|
|
164 #define SDL_BYTEORDER SDL_BIG_ENDIAN
|
|
|
165 #else
|
|
|
166 #define SDL_BYTEORDER SDL_LIL_ENDIAN
|
|
|
167 #endif
|
|
|
168 #endif /* SDL_PLATFORM_LINUX */
|
|
|
169 #endif /* !SDL_BYTEORDER */
|
|
|
170
|
|
|
171 #ifndef SDL_FLOATWORDORDER
|
|
|
172 #ifdef SDL_WIKI_DOCUMENTATION_SECTION
|
|
|
173
|
|
|
174 /**
|
|
|
175 * A macro that reports the target system's floating point word order.
|
|
|
176 *
|
|
|
177 * This is set to either SDL_LIL_ENDIAN or SDL_BIG_ENDIAN (and maybe other
|
|
|
178 * values in the future, if something else becomes popular). This can be
|
|
|
179 * tested with the preprocessor, so decisions can be made at compile time.
|
|
|
180 *
|
|
|
181 * ```c
|
|
|
182 * #if SDL_FLOATWORDORDER == SDL_BIG_ENDIAN
|
|
|
183 * SDL_Log("This system's floats are bigendian.");
|
|
|
184 * #endif
|
|
|
185 * ```
|
|
|
186 *
|
|
|
187 * \since This macro is available since SDL 3.2.0.
|
|
|
188 *
|
|
|
189 * \sa SDL_LIL_ENDIAN
|
|
|
190 * \sa SDL_BIG_ENDIAN
|
|
|
191 */
|
|
|
192 #define SDL_FLOATWORDORDER SDL_LIL_ENDIAN___or_maybe___SDL_BIG_ENDIAN
|
|
|
193 /* predefs from newer gcc versions: */
|
|
|
194 #elif defined(__ORDER_LITTLE_ENDIAN__) && defined(__ORDER_BIG_ENDIAN__) && defined(__FLOAT_WORD_ORDER__)
|
|
|
195 #if (__FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__)
|
|
|
196 #define SDL_FLOATWORDORDER SDL_LIL_ENDIAN
|
|
|
197 #elif (__FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__)
|
|
|
198 #define SDL_FLOATWORDORDER SDL_BIG_ENDIAN
|
|
|
199 #else
|
|
|
200 #error Unsupported endianness
|
|
|
201 #endif /**/
|
|
|
202 #elif defined(__MAVERICK__)
|
|
|
203 /* For Maverick, float words are always little-endian. */
|
|
|
204 #define SDL_FLOATWORDORDER SDL_LIL_ENDIAN
|
|
|
205 #elif (defined(__arm__) || defined(__thumb__)) && !defined(__VFP_FP__) && !defined(__ARM_EABI__)
|
|
|
206 /* For FPA, float words are always big-endian. */
|
|
|
207 #define SDL_FLOATWORDORDER SDL_BIG_ENDIAN
|
|
|
208 #else
|
|
|
209 /* By default, assume that floats words follow the memory system mode. */
|
|
|
210 #define SDL_FLOATWORDORDER SDL_BYTEORDER
|
|
|
211 #endif /* __FLOAT_WORD_ORDER__ */
|
|
|
212 #endif /* !SDL_FLOATWORDORDER */
|
|
|
213
|
|
|
214
|
|
|
215 #include <SDL3/SDL_begin_code.h>
|
|
|
216 /* Set up for C function definitions, even when using C++ */
|
|
|
217 #ifdef __cplusplus
|
|
|
218 extern "C" {
|
|
|
219 #endif
|
|
|
220
|
|
|
221 /* various modern compilers may have builtin swap */
|
|
|
222 #if defined(__GNUC__) || defined(__clang__)
|
|
|
223 # define HAS_BUILTIN_BSWAP16 (SDL_HAS_BUILTIN(__builtin_bswap16)) || \
|
|
|
224 (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))
|
|
|
225 # define HAS_BUILTIN_BSWAP32 (SDL_HAS_BUILTIN(__builtin_bswap32)) || \
|
|
|
226 (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
|
|
|
227 # define HAS_BUILTIN_BSWAP64 (SDL_HAS_BUILTIN(__builtin_bswap64)) || \
|
|
|
228 (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
|
|
|
229
|
|
|
230 /* this one is broken */
|
|
|
231 # define HAS_BROKEN_BSWAP (__GNUC__ == 2 && __GNUC_MINOR__ <= 95)
|
|
|
232 #else
|
|
|
233 # define HAS_BUILTIN_BSWAP16 0
|
|
|
234 # define HAS_BUILTIN_BSWAP32 0
|
|
|
235 # define HAS_BUILTIN_BSWAP64 0
|
|
|
236 # define HAS_BROKEN_BSWAP 0
|
|
|
237 #endif
|
|
|
238
|
|
|
239 /* Byte swap 16-bit integer. */
|
|
|
240 #ifndef SDL_WIKI_DOCUMENTATION_SECTION
|
|
|
241 #if HAS_BUILTIN_BSWAP16
|
|
|
242 #define SDL_Swap16(x) __builtin_bswap16(x)
|
|
|
243 #elif (defined(_MSC_VER) && (_MSC_VER >= 1400)) && !defined(__ICL)
|
|
|
244 #pragma intrinsic(_byteswap_ushort)
|
|
|
245 #define SDL_Swap16(x) _byteswap_ushort(x)
|
|
|
246 #elif defined(__i386__) && !HAS_BROKEN_BSWAP
|
|
|
247 SDL_FORCE_INLINE Uint16 SDL_Swap16(Uint16 x)
|
|
|
248 {
|
|
|
249 __asm__("xchgb %b0,%h0": "=q"(x):"0"(x));
|
|
|
250 return x;
|
|
|
251 }
|
|
|
252 #elif defined(__x86_64__)
|
|
|
253 SDL_FORCE_INLINE Uint16 SDL_Swap16(Uint16 x)
|
|
|
254 {
|
|
|
255 __asm__("xchgb %b0,%h0": "=abcd"(x):"0"(x));
|
|
|
256 return x;
|
|
|
257 }
|
|
|
258 #elif (defined(__powerpc__) || defined(__ppc__))
|
|
|
259 SDL_FORCE_INLINE Uint16 SDL_Swap16(Uint16 x)
|
|
|
260 {
|
|
|
261 int result;
|
|
|
262
|
|
|
263 __asm__("rlwimi %0,%2,8,16,23": "=&r"(result):"0"(x >> 8), "r"(x));
|
|
|
264 return (Uint16)result;
|
|
|
265 }
|
|
|
266 #elif (defined(__m68k__) && !defined(__mcoldfire__))
|
|
|
267 SDL_FORCE_INLINE Uint16 SDL_Swap16(Uint16 x)
|
|
|
268 {
|
|
|
269 __asm__("rorw #8,%0": "=d"(x): "0"(x):"cc");
|
|
|
270 return x;
|
|
|
271 }
|
|
|
272 #elif defined(__WATCOMC__) && defined(__386__)
|
|
|
273 extern __inline Uint16 SDL_Swap16(Uint16);
|
|
|
274 #pragma aux SDL_Swap16 = \
|
|
|
275 "xchg al, ah" \
|
|
|
276 parm [ax] \
|
|
|
277 modify [ax];
|
|
|
278 #else
|
|
|
279 SDL_FORCE_INLINE Uint16 SDL_Swap16(Uint16 x)
|
|
|
280 {
|
|
|
281 return SDL_static_cast(Uint16, ((x << 8) | (x >> 8)));
|
|
|
282 }
|
|
|
283 #endif
|
|
|
284 #endif
|
|
|
285
|
|
|
286 /* Byte swap 32-bit integer. */
|
|
|
287 #ifndef SDL_WIKI_DOCUMENTATION_SECTION
|
|
|
288 #if HAS_BUILTIN_BSWAP32
|
|
|
289 #define SDL_Swap32(x) __builtin_bswap32(x)
|
|
|
290 #elif (defined(_MSC_VER) && (_MSC_VER >= 1400)) && !defined(__ICL)
|
|
|
291 #pragma intrinsic(_byteswap_ulong)
|
|
|
292 #define SDL_Swap32(x) _byteswap_ulong(x)
|
|
|
293 #elif defined(__i386__) && !HAS_BROKEN_BSWAP
|
|
|
294 SDL_FORCE_INLINE Uint32 SDL_Swap32(Uint32 x)
|
|
|
295 {
|
|
|
296 __asm__("bswap %0": "=r"(x):"0"(x));
|
|
|
297 return x;
|
|
|
298 }
|
|
|
299 #elif defined(__x86_64__)
|
|
|
300 SDL_FORCE_INLINE Uint32 SDL_Swap32(Uint32 x)
|
|
|
301 {
|
|
|
302 __asm__("bswapl %0": "=r"(x):"0"(x));
|
|
|
303 return x;
|
|
|
304 }
|
|
|
305 #elif (defined(__powerpc__) || defined(__ppc__))
|
|
|
306 SDL_FORCE_INLINE Uint32 SDL_Swap32(Uint32 x)
|
|
|
307 {
|
|
|
308 Uint32 result;
|
|
|
309
|
|
|
310 __asm__("rlwimi %0,%2,24,16,23": "=&r"(result): "0" (x>>24), "r"(x));
|
|
|
311 __asm__("rlwimi %0,%2,8,8,15" : "=&r"(result): "0" (result), "r"(x));
|
|
|
312 __asm__("rlwimi %0,%2,24,0,7" : "=&r"(result): "0" (result), "r"(x));
|
|
|
313 return result;
|
|
|
314 }
|
|
|
315 #elif (defined(__m68k__) && !defined(__mcoldfire__))
|
|
|
316 SDL_FORCE_INLINE Uint32 SDL_Swap32(Uint32 x)
|
|
|
317 {
|
|
|
318 __asm__("rorw #8,%0\n\tswap %0\n\trorw #8,%0": "=d"(x): "0"(x):"cc");
|
|
|
319 return x;
|
|
|
320 }
|
|
|
321 #elif defined(__WATCOMC__) && defined(__386__)
|
|
|
322 extern __inline Uint32 SDL_Swap32(Uint32);
|
|
|
323 #pragma aux SDL_Swap32 = \
|
|
|
324 "bswap eax" \
|
|
|
325 parm [eax] \
|
|
|
326 modify [eax];
|
|
|
327 #else
|
|
|
328 SDL_FORCE_INLINE Uint32 SDL_Swap32(Uint32 x)
|
|
|
329 {
|
|
|
330 return SDL_static_cast(Uint32, ((x << 24) | ((x << 8) & 0x00FF0000) |
|
|
|
331 ((x >> 8) & 0x0000FF00) | (x >> 24)));
|
|
|
332 }
|
|
|
333 #endif
|
|
|
334 #endif
|
|
|
335
|
|
|
336 /* Byte swap 64-bit integer. */
|
|
|
337 #ifndef SDL_WIKI_DOCUMENTATION_SECTION
|
|
|
338 #if HAS_BUILTIN_BSWAP64
|
|
|
339 #define SDL_Swap64(x) __builtin_bswap64(x)
|
|
|
340 #elif (defined(_MSC_VER) && (_MSC_VER >= 1400)) && !defined(__ICL)
|
|
|
341 #pragma intrinsic(_byteswap_uint64)
|
|
|
342 #define SDL_Swap64(x) _byteswap_uint64(x)
|
|
|
343 #elif defined(__i386__) && !HAS_BROKEN_BSWAP
|
|
|
344 SDL_FORCE_INLINE Uint64 SDL_Swap64(Uint64 x)
|
|
|
345 {
|
|
|
346 union {
|
|
|
347 struct {
|
|
|
348 Uint32 a, b;
|
|
|
349 } s;
|
|
|
350 Uint64 u;
|
|
|
351 } v;
|
|
|
352 v.u = x;
|
|
|
353 __asm__("bswapl %0 ; bswapl %1 ; xchgl %0,%1"
|
|
|
354 : "=r"(v.s.a), "=r"(v.s.b)
|
|
|
355 : "0" (v.s.a), "1"(v.s.b));
|
|
|
356 return v.u;
|
|
|
357 }
|
|
|
358 #elif defined(__x86_64__)
|
|
|
359 SDL_FORCE_INLINE Uint64 SDL_Swap64(Uint64 x)
|
|
|
360 {
|
|
|
361 __asm__("bswapq %0": "=r"(x):"0"(x));
|
|
|
362 return x;
|
|
|
363 }
|
|
|
364 #elif defined(__WATCOMC__) && defined(__386__)
|
|
|
365 extern __inline Uint64 SDL_Swap64(Uint64);
|
|
|
366 #pragma aux SDL_Swap64 = \
|
|
|
367 "bswap eax" \
|
|
|
368 "bswap edx" \
|
|
|
369 "xchg eax,edx" \
|
|
|
370 parm [eax edx] \
|
|
|
371 modify [eax edx];
|
|
|
372 #else
|
|
|
373 SDL_FORCE_INLINE Uint64 SDL_Swap64(Uint64 x)
|
|
|
374 {
|
|
|
375 Uint32 hi, lo;
|
|
|
376
|
|
|
377 /* Separate into high and low 32-bit values and swap them */
|
|
|
378 lo = SDL_static_cast(Uint32, x & 0xFFFFFFFF);
|
|
|
379 x >>= 32;
|
|
|
380 hi = SDL_static_cast(Uint32, x & 0xFFFFFFFF);
|
|
|
381 x = SDL_Swap32(lo);
|
|
|
382 x <<= 32;
|
|
|
383 x |= SDL_Swap32(hi);
|
|
|
384 return (x);
|
|
|
385 }
|
|
|
386 #endif
|
|
|
387 #endif
|
|
|
388
|
|
|
389 /**
|
|
|
390 * Byte-swap a floating point number.
|
|
|
391 *
|
|
|
392 * This will always byte-swap the value, whether it's currently in the native
|
|
|
393 * byteorder of the system or not. You should use SDL_SwapFloatLE or
|
|
|
394 * SDL_SwapFloatBE instead, in most cases.
|
|
|
395 *
|
|
|
396 * Note that this is a forced-inline function in a header, and not a public
|
|
|
397 * API function available in the SDL library (which is to say, the code is
|
|
|
398 * embedded in the calling program and the linker and dynamic loader will not
|
|
|
399 * be able to find this function inside SDL itself).
|
|
|
400 *
|
|
|
401 * \param x the value to byte-swap.
|
|
|
402 * \returns x, with its bytes in the opposite endian order.
|
|
|
403 *
|
|
|
404 * \threadsafety It is safe to call this function from any thread.
|
|
|
405 *
|
|
|
406 * \since This function is available since SDL 3.2.0.
|
|
|
407 */
|
|
|
408 SDL_FORCE_INLINE float SDL_SwapFloat(float x)
|
|
|
409 {
|
|
|
410 union {
|
|
|
411 float f;
|
|
|
412 Uint32 ui32;
|
|
|
413 } swapper;
|
|
|
414 swapper.f = x;
|
|
|
415 swapper.ui32 = SDL_Swap32(swapper.ui32);
|
|
|
416 return swapper.f;
|
|
|
417 }
|
|
|
418
|
|
|
419 /* remove extra macros */
|
|
|
420 #undef HAS_BROKEN_BSWAP
|
|
|
421 #undef HAS_BUILTIN_BSWAP16
|
|
|
422 #undef HAS_BUILTIN_BSWAP32
|
|
|
423 #undef HAS_BUILTIN_BSWAP64
|
|
|
424
|
|
|
425
|
|
|
426 #ifdef SDL_WIKI_DOCUMENTATION_SECTION
|
|
|
427
|
|
|
428 /**
|
|
|
429 * Byte-swap an unsigned 16-bit number.
|
|
|
430 *
|
|
|
431 * This will always byte-swap the value, whether it's currently in the native
|
|
|
432 * byteorder of the system or not. You should use SDL_Swap16LE or SDL_Swap16BE
|
|
|
433 * instead, in most cases.
|
|
|
434 *
|
|
|
435 * Note that this is a forced-inline function in a header, and not a public
|
|
|
436 * API function available in the SDL library (which is to say, the code is
|
|
|
437 * embedded in the calling program and the linker and dynamic loader will not
|
|
|
438 * be able to find this function inside SDL itself).
|
|
|
439 *
|
|
|
440 * \param x the value to byte-swap.
|
|
|
441 * \returns `x`, with its bytes in the opposite endian order.
|
|
|
442 *
|
|
|
443 * \threadsafety It is safe to call this function from any thread.
|
|
|
444 *
|
|
|
445 * \since This function is available since SDL 3.2.0.
|
|
|
446 */
|
|
|
447 SDL_FORCE_INLINE Uint16 SDL_Swap16(Uint16 x) { return x_but_byteswapped; }
|
|
|
448
|
|
|
449 /**
|
|
|
450 * Byte-swap an unsigned 32-bit number.
|
|
|
451 *
|
|
|
452 * This will always byte-swap the value, whether it's currently in the native
|
|
|
453 * byteorder of the system or not. You should use SDL_Swap32LE or SDL_Swap32BE
|
|
|
454 * instead, in most cases.
|
|
|
455 *
|
|
|
456 * Note that this is a forced-inline function in a header, and not a public
|
|
|
457 * API function available in the SDL library (which is to say, the code is
|
|
|
458 * embedded in the calling program and the linker and dynamic loader will not
|
|
|
459 * be able to find this function inside SDL itself).
|
|
|
460 *
|
|
|
461 * \param x the value to byte-swap.
|
|
|
462 * \returns `x`, with its bytes in the opposite endian order.
|
|
|
463 *
|
|
|
464 * \threadsafety It is safe to call this function from any thread.
|
|
|
465 *
|
|
|
466 * \since This function is available since SDL 3.2.0.
|
|
|
467 */
|
|
|
468 SDL_FORCE_INLINE Uint32 SDL_Swap32(Uint32 x) { return x_but_byteswapped; }
|
|
|
469
|
|
|
470 /**
|
|
|
471 * Byte-swap an unsigned 64-bit number.
|
|
|
472 *
|
|
|
473 * This will always byte-swap the value, whether it's currently in the native
|
|
|
474 * byteorder of the system or not. You should use SDL_Swap64LE or SDL_Swap64BE
|
|
|
475 * instead, in most cases.
|
|
|
476 *
|
|
|
477 * Note that this is a forced-inline function in a header, and not a public
|
|
|
478 * API function available in the SDL library (which is to say, the code is
|
|
|
479 * embedded in the calling program and the linker and dynamic loader will not
|
|
|
480 * be able to find this function inside SDL itself).
|
|
|
481 *
|
|
|
482 * \param x the value to byte-swap.
|
|
|
483 * \returns `x`, with its bytes in the opposite endian order.
|
|
|
484 *
|
|
|
485 * \threadsafety It is safe to call this function from any thread.
|
|
|
486 *
|
|
|
487 * \since This function is available since SDL 3.2.0.
|
|
|
488 */
|
|
|
489 SDL_FORCE_INLINE Uint64 SDL_Swap64(Uint64 x) { return x_but_byteswapped; }
|
|
|
490
|
|
|
491 /**
|
|
|
492 * Swap a 16-bit value from littleendian to native byte order.
|
|
|
493 *
|
|
|
494 * If this is running on a littleendian system, `x` is returned unchanged.
|
|
|
495 *
|
|
|
496 * This macro never references `x` more than once, avoiding side effects.
|
|
|
497 *
|
|
|
498 * \param x the value to swap, in littleendian byte order.
|
|
|
499 * \returns `x` in native byte order.
|
|
|
500 *
|
|
|
501 * \threadsafety It is safe to call this macro from any thread.
|
|
|
502 *
|
|
|
503 * \since This macro is available since SDL 3.2.0.
|
|
|
504 */
|
|
|
505 #define SDL_Swap16LE(x) SwapOnlyIfNecessary(x)
|
|
|
506
|
|
|
507 /**
|
|
|
508 * Swap a 32-bit value from littleendian to native byte order.
|
|
|
509 *
|
|
|
510 * If this is running on a littleendian system, `x` is returned unchanged.
|
|
|
511 *
|
|
|
512 * This macro never references `x` more than once, avoiding side effects.
|
|
|
513 *
|
|
|
514 * \param x the value to swap, in littleendian byte order.
|
|
|
515 * \returns `x` in native byte order.
|
|
|
516 *
|
|
|
517 * \threadsafety It is safe to call this macro from any thread.
|
|
|
518 *
|
|
|
519 * \since This macro is available since SDL 3.2.0.
|
|
|
520 */
|
|
|
521 #define SDL_Swap32LE(x) SwapOnlyIfNecessary(x)
|
|
|
522
|
|
|
523 /**
|
|
|
524 * Swap a 64-bit value from littleendian to native byte order.
|
|
|
525 *
|
|
|
526 * If this is running on a littleendian system, `x` is returned unchanged.
|
|
|
527 *
|
|
|
528 * This macro never references `x` more than once, avoiding side effects.
|
|
|
529 *
|
|
|
530 * \param x the value to swap, in littleendian byte order.
|
|
|
531 * \returns `x` in native byte order.
|
|
|
532 *
|
|
|
533 * \threadsafety It is safe to call this macro from any thread.
|
|
|
534 *
|
|
|
535 * \since This macro is available since SDL 3.2.0.
|
|
|
536 */
|
|
|
537 #define SDL_Swap64LE(x) SwapOnlyIfNecessary(x)
|
|
|
538
|
|
|
539 /**
|
|
|
540 * Swap a floating point value from littleendian to native byte order.
|
|
|
541 *
|
|
|
542 * If this is running on a littleendian system, `x` is returned unchanged.
|
|
|
543 *
|
|
|
544 * This macro never references `x` more than once, avoiding side effects.
|
|
|
545 *
|
|
|
546 * \param x the value to swap, in littleendian byte order.
|
|
|
547 * \returns `x` in native byte order.
|
|
|
548 *
|
|
|
549 * \threadsafety It is safe to call this macro from any thread.
|
|
|
550 *
|
|
|
551 * \since This macro is available since SDL 3.2.0.
|
|
|
552 */
|
|
|
553 #define SDL_SwapFloatLE(x) SwapOnlyIfNecessary(x)
|
|
|
554
|
|
|
555 /**
|
|
|
556 * Swap a 16-bit value from bigendian to native byte order.
|
|
|
557 *
|
|
|
558 * If this is running on a bigendian system, `x` is returned unchanged.
|
|
|
559 *
|
|
|
560 * This macro never references `x` more than once, avoiding side effects.
|
|
|
561 *
|
|
|
562 * \param x the value to swap, in bigendian byte order.
|
|
|
563 * \returns `x` in native byte order.
|
|
|
564 *
|
|
|
565 * \threadsafety It is safe to call this macro from any thread.
|
|
|
566 *
|
|
|
567 * \since This macro is available since SDL 3.2.0.
|
|
|
568 */
|
|
|
569 #define SDL_Swap16BE(x) SwapOnlyIfNecessary(x)
|
|
|
570
|
|
|
571 /**
|
|
|
572 * Swap a 32-bit value from bigendian to native byte order.
|
|
|
573 *
|
|
|
574 * If this is running on a bigendian system, `x` is returned unchanged.
|
|
|
575 *
|
|
|
576 * This macro never references `x` more than once, avoiding side effects.
|
|
|
577 *
|
|
|
578 * \param x the value to swap, in bigendian byte order.
|
|
|
579 * \returns `x` in native byte order.
|
|
|
580 *
|
|
|
581 * \threadsafety It is safe to call this macro from any thread.
|
|
|
582 *
|
|
|
583 * \since This macro is available since SDL 3.2.0.
|
|
|
584 */
|
|
|
585 #define SDL_Swap32BE(x) SwapOnlyIfNecessary(x)
|
|
|
586
|
|
|
587 /**
|
|
|
588 * Swap a 64-bit value from bigendian to native byte order.
|
|
|
589 *
|
|
|
590 * If this is running on a bigendian system, `x` is returned unchanged.
|
|
|
591 *
|
|
|
592 * This macro never references `x` more than once, avoiding side effects.
|
|
|
593 *
|
|
|
594 * \param x the value to swap, in bigendian byte order.
|
|
|
595 * \returns `x` in native byte order.
|
|
|
596 *
|
|
|
597 * \threadsafety It is safe to call this macro from any thread.
|
|
|
598 *
|
|
|
599 * \since This macro is available since SDL 3.2.0.
|
|
|
600 */
|
|
|
601 #define SDL_Swap64BE(x) SwapOnlyIfNecessary(x)
|
|
|
602
|
|
|
603 /**
|
|
|
604 * Swap a floating point value from bigendian to native byte order.
|
|
|
605 *
|
|
|
606 * If this is running on a bigendian system, `x` is returned unchanged.
|
|
|
607 *
|
|
|
608 * This macro never references `x` more than once, avoiding side effects.
|
|
|
609 *
|
|
|
610 * \param x the value to swap, in bigendian byte order.
|
|
|
611 * \returns `x` in native byte order.
|
|
|
612 *
|
|
|
613 * \threadsafety It is safe to call this macro from any thread.
|
|
|
614 *
|
|
|
615 * \since This macro is available since SDL 3.2.0.
|
|
|
616 */
|
|
|
617 #define SDL_SwapFloatBE(x) SwapOnlyIfNecessary(x)
|
|
|
618
|
|
|
619 #elif SDL_BYTEORDER == SDL_LIL_ENDIAN
|
|
|
620 #define SDL_Swap16LE(x) (x)
|
|
|
621 #define SDL_Swap32LE(x) (x)
|
|
|
622 #define SDL_Swap64LE(x) (x)
|
|
|
623 #define SDL_SwapFloatLE(x) (x)
|
|
|
624 #define SDL_Swap16BE(x) SDL_Swap16(x)
|
|
|
625 #define SDL_Swap32BE(x) SDL_Swap32(x)
|
|
|
626 #define SDL_Swap64BE(x) SDL_Swap64(x)
|
|
|
627 #define SDL_SwapFloatBE(x) SDL_SwapFloat(x)
|
|
|
628 #else
|
|
|
629 #define SDL_Swap16LE(x) SDL_Swap16(x)
|
|
|
630 #define SDL_Swap32LE(x) SDL_Swap32(x)
|
|
|
631 #define SDL_Swap64LE(x) SDL_Swap64(x)
|
|
|
632 #define SDL_SwapFloatLE(x) SDL_SwapFloat(x)
|
|
|
633 #define SDL_Swap16BE(x) (x)
|
|
|
634 #define SDL_Swap32BE(x) (x)
|
|
|
635 #define SDL_Swap64BE(x) (x)
|
|
|
636 #define SDL_SwapFloatBE(x) (x)
|
|
|
637 #endif
|
|
|
638
|
|
|
639 /* Ends C function definitions when using C++ */
|
|
|
640 #ifdef __cplusplus
|
|
|
641 }
|
|
|
642 #endif
|
|
|
643 #include <SDL3/SDL_close_code.h>
|
|
|
644
|
|
|
645 #endif /* SDL_endian_h_ */
|