Add SDL_FLOATWORDORDER for older ARM toolchains
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 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
diff --git a/include/SDL_endian.h b/include/SDL_endian.h
index 2866f4b..e1c6b5e 100644
--- a/include/SDL_endian.h
+++ b/include/SDL_endian.h
@@ -87,6 +87,28 @@ _m_prefetch(void *__P)
#endif /* __linux__ */
#endif /* !SDL_BYTEORDER */
+#ifndef SDL_FLOATWORDORDER /* Not defined in SDL_config.h? */
+/* predefs from newer gcc versions: */
+#if defined(__ORDER_LITTLE_ENDIAN__) && defined(__ORDER_BIG_ENDIAN__) && defined(__FLOAT_WORD_ORDER__)
+#if (__FLOAT_WORD_ORDER__ == __ORDER_LITTLE_ENDIAN__)
+#define SDL_FLOATWORDORDER SDL_LIL_ENDIAN
+#elif (__FLOAT_WORD_ORDER__ == __ORDER_BIG_ENDIAN__)
+#define SDL_FLOATWORDORDER SDL_BIG_ENDIAN
+#else
+#error Unsupported endianness
+#endif /**/
+#elif defined(__MAVERICK__)
+/* For Maverick, float words are always little-endian. */
+#define SDL_FLOATWORDORDER SDL_LIL_ENDIAN
+#elif (defined(__arm__) || defined(__thumb__)) && !defined(__VFP_FP__) && !defined(__ARM_EABI__)
+/* For FPA, float words are always big-endian. */
+#define SDL_FLOATWORDORDER SDL_BIG_ENDIAN
+#else
+/* By default, assume that floats words follow the memory system mode. */
+#define SDL_FLOATWORDORDER SDL_BYTEORDER
+#endif /* __FLOAT_WORD_ORDER__ */
+#endif /* !SDL_FLOATWORDORDER */
+
#include "begin_code.h"
/* Set up for C function definitions, even when using C++ */
diff --git a/src/libm/math_private.h b/src/libm/math_private.h
index 4a30a52..2e4bb14 100644
--- a/src/libm/math_private.h
+++ b/src/libm/math_private.h
@@ -66,9 +66,10 @@ typedef unsigned int u_int32_t;
* Math on arm is special:
* For FPA, float words are always big-endian.
* For VFP, floats words follow the memory system mode.
+ * For Maverick, float words are always little-endian.
*/
-#if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
+#if (SDL_FLOATWORDORDER == SDL_BIG_ENDIAN)
typedef union
{
diff --git a/test/testautomation_platform.c b/test/testautomation_platform.c
index 4e28ba1..0a31ad8 100644
--- a/test/testautomation_platform.c
+++ b/test/testautomation_platform.c
@@ -54,12 +54,18 @@ int platform_testTypes(void *arg)
int platform_testEndianessAndSwap(void *arg)
{
int real_byteorder;
+ int real_floatwordorder = 0;
Uint16 value = 0x1234;
Uint16 value16 = 0xCDAB;
Uint16 swapped16 = 0xABCD;
Uint32 value32 = 0xEFBEADDE;
Uint32 swapped32 = 0xDEADBEEF;
+ union {
+ double d;
+ Uint32 ui32[2];
+ } value_double;
+
Uint64 value64, swapped64;
value64 = 0xEFBEADDE;
value64 <<= 32;
@@ -67,6 +73,7 @@ int platform_testEndianessAndSwap(void *arg)
swapped64 = 0x1234ABCD;
swapped64 <<= 32;
swapped64 |= 0xDEADBEEF;
+ value_double.d = 3.141593;
if ((*((char *) &value) >> 4) == 0x1) {
real_byteorder = SDL_BIG_ENDIAN;
@@ -80,6 +87,18 @@ int platform_testEndianessAndSwap(void *arg)
(SDL_BYTEORDER == SDL_LIL_ENDIAN) ? "little" : "big",
(real_byteorder == SDL_LIL_ENDIAN) ? "little" : "big" );
+ if (value_double.ui32[0] == 0x82c2bd7f && value_double.ui32[1] == 0x400921fb) {
+ real_floatwordorder = SDL_LIL_ENDIAN;
+ } else if (value_double.ui32[0] == 0x400921fb && value_double.ui32[1] == 0x82c2bd7f) {
+ real_floatwordorder = SDL_BIG_ENDIAN;
+ }
+
+ /* Test endianness. */
+ SDLTest_AssertCheck( real_floatwordorder == SDL_FLOATWORDORDER,
+ "Machine detected as having %s endian float word order, appears to be %s endian.",
+ (SDL_FLOATWORDORDER == SDL_LIL_ENDIAN) ? "little" : "big",
+ (real_floatwordorder == SDL_LIL_ENDIAN) ? "little" : (real_floatwordorder == SDL_BIG_ENDIAN) ? "big" : "unknown" );
+
/* Test 16 swap. */
SDLTest_AssertCheck( SDL_Swap16(value16) == swapped16,
"SDL_Swap16(): 16 bit swapped: 0x%X => 0x%X",
diff --git a/test/testplatform.c b/test/testplatform.c
index 5aa649c..f5b524d 100644
--- a/test/testplatform.c
+++ b/test/testplatform.c
@@ -86,18 +86,25 @@ TestEndian(SDL_bool verbose)
int error = 0;
Uint16 value = 0x1234;
int real_byteorder;
+ int real_floatwordorder = 0;
Uint16 value16 = 0xCDAB;
Uint16 swapped16 = 0xABCD;
Uint32 value32 = 0xEFBEADDE;
Uint32 swapped32 = 0xDEADBEEF;
Uint64 value64, swapped64;
+ union {
+ double d;
+ Uint32 ui32[2];
+ } value_double;
+
value64 = 0xEFBEADDE;
value64 <<= 32;
value64 |= 0xCDAB3412;
swapped64 = 0x1234ABCD;
swapped64 <<= 32;
swapped64 |= 0xDEADBEEF;
+ value_double.d = 3.141593;
if (verbose) {
SDL_Log("Detected a %s endian machine.\n",
@@ -116,6 +123,22 @@ TestEndian(SDL_bool verbose)
++error;
}
if (verbose) {
+ SDL_Log("Detected a %s endian float word order machine.\n",
+ (SDL_FLOATWORDORDER == SDL_LIL_ENDIAN) ? "little" : "big");
+ }
+ if (value_double.ui32[0] == 0x82c2bd7f && value_double.ui32[1] == 0x400921fb) {
+ real_floatwordorder = SDL_LIL_ENDIAN;
+ } else if (value_double.ui32[0] == 0x400921fb && value_double.ui32[1] == 0x82c2bd7f) {
+ real_floatwordorder = SDL_BIG_ENDIAN;
+ }
+ if (real_floatwordorder != SDL_FLOATWORDORDER) {
+ if (verbose) {
+ SDL_Log("Actually a %s endian float word order machine!\n",
+ (real_floatwordorder == SDL_LIL_ENDIAN) ? "little" : (real_floatwordorder == SDL_BIG_ENDIAN) ? "big" : "unknown" );
+ }
+ ++error;
+ }
+ if (verbose) {
SDL_Log("Value 16 = 0x%X, swapped = 0x%X\n", value16,
SDL_Swap16(value16));
}