aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/endian.h101
1 files changed, 53 insertions, 48 deletions
diff --git a/common/endian.h b/common/endian.h
index 9a6c0cd42c..9f10b63053 100644
--- a/common/endian.h
+++ b/common/endian.h
@@ -71,64 +71,36 @@
((uint16)((((a) >> 8) & 0x00FF) | \
(((a) << 8) & 0xFF00) ))
-#ifdef HAVE_INT64
+
+
/**
- * Swap the bytes in a 64 bit word in order to convert LE encoded data to BE
+ * Swap the bytes in a 16 bit word in order to convert LE encoded data to BE
* and vice versa.
*/
-// machine/compiler-specific variants come first, fallback last
+// compilerspecific variants come first, fallback last
// Test for GCC and if the target has the MIPS rel.2 instructions (we know the psp does)
-//
-// TODO: Fix this #if statement. It isn't changed from 32 bit. Is there a 64 bit swap instruction?
#if defined(__GNUC__) && (defined(__psp__) || defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2))
- FORCEINLINE uint32 SWAP_BYTES_32(const uint32 a) {
+ FORCEINLINE uint16 SWAP_BYTES_16(const uint16 a) {
if (__builtin_constant_p(a)) {
- return SWAP_CONSTANT_32(a);
+ return SWAP_CONSTANT_16(a);
} else {
- uint32 result;
-# if defined(__psp__)
- // use special allegrex instruction
- __asm__ ("wsbw %0,%1" : "=r" (result) : "r" (a));
-# else
- __asm__ ("wsbh %0,%1\n"
- "rotr %0,%0,16" : "=r" (result) : "r" (a));
-# endif
+ uint16 result;
+ __asm__ ("wsbh %0,%1" : "=r" (result) : "r" (a));
return result;
}
}
-
-// Test for GCC >= 4.3.0 as this version added the bswap builtin
-#elif GCC_ATLEAST(4, 3)
-
- FORCEINLINE uint64 SWAP_BYTES_64(uint64 a) {
- return __builtin_bswap64(a);
- }
-
-#elif defined(_MSC_VER)
-
- FORCEINLINE uint64 SWAP_BYTES_64(uint64 a) {
- return _byteswap_uint64(a);
- }
-
-// generic fallback
#else
- inline uint64 SWAP_BYTES_64(uint64 a) {
- uint32 low = (uint32)a, high = (uint32)(a >> 32);
- uint16 lowLow = (uint16)low, lowHigh = (uint16)(low >> 16),
- highLow = (uint16)high, highHigh = (uint16)(high >> 16);
-
- return ((uint64)(((uint32)(uint16)((lowLow >> 8) | (lowLow << 8)) << 16) |
- (uint16)((lowHigh >> 8) | (lowHigh << 8))) << 32) |
- (((uint32)(uint16)((highLow >> 8) | (highLow << 8)) << 16) |
- (uint16)((highHigh >> 8) | (highHigh << 8)));
+ inline uint16 SWAP_BYTES_16(const uint16 a) {
+ return (a >> 8) | (a << 8);
}
#endif
-#endif // HAVE_INT64
+
+
/**
* Swap the bytes in a 32 bit word in order to convert LE encoded data to BE
* and vice versa.
@@ -178,32 +150,65 @@
}
#endif
+#ifdef HAVE_INT64
/**
- * Swap the bytes in a 16 bit word in order to convert LE encoded data to BE
+ * Swap the bytes in a 64 bit word in order to convert LE encoded data to BE
* and vice versa.
*/
-// compilerspecific variants come first, fallback last
+// machine/compiler-specific variants come first, fallback last
// Test for GCC and if the target has the MIPS rel.2 instructions (we know the psp does)
+//
+// TODO: Fix this #if statement. It isn't changed from 32 bit. Is there a 64 bit swap instruction?
#if defined(__GNUC__) && (defined(__psp__) || defined(_MIPS_ARCH_MIPS32R2) || defined(_MIPS_ARCH_MIPS64R2))
- FORCEINLINE uint16 SWAP_BYTES_16(const uint16 a) {
+ FORCEINLINE uint32 SWAP_BYTES_32(const uint32 a) {
if (__builtin_constant_p(a)) {
- return SWAP_CONSTANT_16(a);
+ return SWAP_CONSTANT_32(a);
} else {
- uint16 result;
- __asm__ ("wsbh %0,%1" : "=r" (result) : "r" (a));
+ uint32 result;
+# if defined(__psp__)
+ // use special allegrex instruction
+ __asm__ ("wsbw %0,%1" : "=r" (result) : "r" (a));
+# else
+ __asm__ ("wsbh %0,%1\n"
+ "rotr %0,%0,16" : "=r" (result) : "r" (a));
+# endif
return result;
}
}
+
+// Test for GCC >= 4.3.0 as this version added the bswap builtin
+#elif GCC_ATLEAST(4, 3)
+
+ FORCEINLINE uint64 SWAP_BYTES_64(uint64 a) {
+ return __builtin_bswap64(a);
+ }
+
+#elif defined(_MSC_VER)
+
+ FORCEINLINE uint64 SWAP_BYTES_64(uint64 a) {
+ return _byteswap_uint64(a);
+ }
+
+// generic fallback
#else
- inline uint16 SWAP_BYTES_16(const uint16 a) {
- return (a >> 8) | (a << 8);
+ inline uint64 SWAP_BYTES_64(uint64 a) {
+ uint32 low = (uint32)a, high = (uint32)(a >> 32);
+ uint16 lowLow = (uint16)low, lowHigh = (uint16)(low >> 16),
+ highLow = (uint16)high, highHigh = (uint16)(high >> 16);
+
+ return ((uint64)(((uint32)(uint16)((lowLow >> 8) | (lowLow << 8)) << 16) |
+ (uint16)((lowHigh >> 8) | (lowHigh << 8))) << 32) |
+ (((uint32)(uint16)((highLow >> 8) | (highLow << 8)) << 16) |
+ (uint16)((highHigh >> 8) | (highHigh << 8)));
}
#endif
+#endif // HAVE_INT64
+
/**
* A wrapper macro used around four character constants, like 'DATA', to