1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
|
From 33aacd4a1e6dda11d5d5a3e0ff11bd8a0eb136d4 Mon Sep 17 00:00:00 2001
From: Jonathan Dowland <jon@dow.land>
Date: Mon, 8 Sep 2025 21:22:50 +0100
Subject: [PATCH] Use runtime endian test for byte swap functions
Remove CPP-branching on endian flags, which meant maintaining two
versions of the byte swap functions. Expand the list of variants
with some missing (e.g. receiving long) to fix compile errors.
Add a runtime host-endian test and runtime conditional branch.
GCC removes these completely on BE and LE with -O1; I suspect
LLVM does too.
---
zdbsp.h | 38 ++++++++++++++++++++++++++++++++------
1 file changed, 32 insertions(+), 6 deletions(-)
diff --git a/zdbsp.h b/zdbsp.h
index 36ef78d..91bf10d 100644
--- a/zdbsp.h
+++ b/zdbsp.h
@@ -237,23 +237,47 @@ inline fixed_t DMulScale32 (fixed_t a, fixed_t b, fixed_t c, fixed_t d)
#define LittleShort(x) CFSwapInt16LittleToHost(x)
#define LittleLong(x) CFSwapInt32LittleToHost(x)
#else
-#ifdef __BIG_ENDIAN__
+
+inline char is_little_endian()
+{
+ const unsigned short one = 1;
+ return *(char *)(&one) == 1;
+}
// Swap 16bit, that is, MSB and LSB byte.
// No masking with 0xFF should be necessary.
inline short LittleShort (short x)
{
+ if(is_little_endian()) {
+ return x;
+ }
return (short)((((unsigned short)x)>>8) | (((unsigned short)x)<<8));
}
inline unsigned short LittleShort (unsigned short x)
{
+ if(is_little_endian()) {
+ return x;
+ }
return (unsigned short)((x>>8) | (x<<8));
}
+inline short LittleShort(int x)
+{
+ return LittleShort((short)x);
+}
+
+inline unsigned short LittleShort (unsigned int x)
+{
+ return LittleShort ((unsigned short)x);
+}
+
// Swapping 32bit.
inline unsigned int LittleLong (unsigned int x)
{
+ if(is_little_endian()) {
+ return x;
+ }
return (unsigned int)(
(x>>24)
| ((x>>8) & 0xff00)
@@ -263,6 +287,9 @@ inline unsigned int LittleLong (unsigned int x)
inline int LittleLong (int x)
{
+ if(is_little_endian()) {
+ return x;
+ }
return (int)(
(((unsigned int)x)>>24)
| ((((unsigned int)x)>>8) & 0xff00)
@@ -270,12 +297,11 @@ inline int LittleLong (int x)
| (((unsigned int)x)<<24));
}
-#else
+inline int LittleLong(long x)
+{
+ return LittleLong((int)x);
+}
-#define LittleShort(x) (x)
-#define LittleLong(x) (x)
-
-#endif // __BIG_ENDIAN__
#endif // __APPLE__
#endif //__ZDBSP_H__
--
2.47.2
|