File: 0001-Use-runtime-endian-test-for-byte-swap-functions.patch

package info (click to toggle)
zdbsp 1.19%2B20181027%2Bdfsg.1-6
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 700 kB
  • sloc: cpp: 9,660; ansic: 1,525; sh: 14; makefile: 7
file content (99 lines) | stat: -rw-r--r-- 2,473 bytes parent folder | download
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