summaryrefslogtreecommitdiff
path: root/firmware/export/system.h
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2011-01-30 00:58:45 +0000
committerMichael Sevakis <jethead71@rockbox.org>2011-01-30 00:58:45 +0000
commit18770dac2e560c88daa3ca9944917be561c3548f (patch)
tree5adf8aef7cb7999a6e07ddefcbb9e1d9bf18a15c /firmware/export/system.h
parentc0c769c5a86c56c2ab2c9e88515a64da98575182 (diff)
downloadrockbox-18770dac2e560c88daa3ca9944917be561c3548f.zip
rockbox-18770dac2e560c88daa3ca9944917be561c3548f.tar.gz
rockbox-18770dac2e560c88daa3ca9944917be561c3548f.tar.bz2
rockbox-18770dac2e560c88daa3ca9944917be561c3548f.tar.xz
Use __builtin_constant_p() to select the best byteswapping method: constant or target optimized. Same macro can then be used for constant values and inits as well as non-constant.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29171 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/export/system.h')
-rw-r--r--firmware/export/system.h129
1 files changed, 69 insertions, 60 deletions
diff --git a/firmware/export/system.h b/firmware/export/system.h
index 4a5dcf0..b246d15 100644
--- a/firmware/export/system.h
+++ b/firmware/export/system.h
@@ -137,61 +137,6 @@ int get_cpu_boost_counter(void);
#undef htobe32
#endif
-/* live endianness conversion */
-#ifdef ROCKBOX_LITTLE_ENDIAN
-#define letoh16(x) (x)
-#define letoh32(x) (x)
-#define htole16(x) (x)
-#define htole32(x) (x)
-#define betoh16(x) swap16(x)
-#define betoh32(x) swap32(x)
-#define htobe16(x) swap16(x)
-#define htobe32(x) swap32(x)
-#define swap_odd_even_be32(x) (x)
-#define swap_odd_even_le32(x) swap_odd_even32(x)
-#else
-#define letoh16(x) swap16(x)
-#define letoh32(x) swap32(x)
-#define htole16(x) swap16(x)
-#define htole32(x) swap32(x)
-#define betoh16(x) (x)
-#define betoh32(x) (x)
-#define htobe16(x) (x)
-#define htobe32(x) (x)
-#define swap_odd_even_be32(x) swap_odd_even32(x)
-#define swap_odd_even_le32(x) (x)
-#endif
-
-
-/* static endianness conversion */
-#define SWAP_16(x) ((typeof(x))(unsigned short)(((unsigned short)(x) >> 8) | \
- ((unsigned short)(x) << 8)))
-
-#define SWAP_32(x) ((typeof(x))(unsigned long)( ((unsigned long)(x) >> 24) | \
- (((unsigned long)(x) & 0xff0000ul) >> 8) | \
- (((unsigned long)(x) & 0xff00ul) << 8) | \
- ((unsigned long)(x) << 24)))
-
-#ifdef ROCKBOX_LITTLE_ENDIAN
-#define LE_TO_H16(x) (x)
-#define LE_TO_H32(x) (x)
-#define H_TO_LE16(x) (x)
-#define H_TO_LE32(x) (x)
-#define BE_TO_H16(x) SWAP_16(x)
-#define BE_TO_H32(x) SWAP_32(x)
-#define H_TO_BE16(x) SWAP_16(x)
-#define H_TO_BE32(x) SWAP_32(x)
-#else
-#define LE_TO_H16(x) SWAP_16(x)
-#define LE_TO_H32(x) SWAP_32(x)
-#define H_TO_LE16(x) SWAP_16(x)
-#define H_TO_LE32(x) SWAP_32(x)
-#define BE_TO_H16(x) (x)
-#define BE_TO_H32(x) (x)
-#define H_TO_BE16(x) (x)
-#define H_TO_BE32(x) (x)
-#endif
-
/* Get the byte offset of a type's member */
#define OFFSETOF(type, membername) ((off_t)&((type *)0)->membername)
@@ -237,7 +182,7 @@ enum {
#endif
#ifdef NEED_GENERIC_BYTESWAPS
-static inline uint16_t swap16(uint16_t value)
+static inline uint16_t swap16_hw(uint16_t value)
/*
result[15..8] = value[ 7..0];
result[ 7..0] = value[15..8];
@@ -246,7 +191,7 @@ static inline uint16_t swap16(uint16_t value)
return (value >> 8) | (value << 8);
}
-static inline uint32_t swap32(uint32_t value)
+static inline uint32_t swap32_hw(uint32_t value)
/*
result[31..24] = value[ 7.. 0];
result[23..16] = value[15.. 8];
@@ -254,12 +199,12 @@ static inline uint32_t swap32(uint32_t value)
result[ 7.. 0] = value[31..24];
*/
{
- uint32_t hi = swap16(value >> 16);
- uint32_t lo = swap16(value & 0xffff);
+ uint32_t hi = swap16_hw(value >> 16);
+ uint32_t lo = swap16_hw(value & 0xffff);
return (lo << 16) | hi;
}
-static inline uint32_t swap_odd_even32(uint32_t value)
+static inline uint32_t swap_odd_even32_hw(uint32_t value)
{
/*
result[31..24],[15.. 8] = value[23..16],[ 7.. 0]
@@ -269,8 +214,72 @@ static inline uint32_t swap_odd_even32(uint32_t value)
return (t >> 8) | ((t ^ value) << 8);
}
+static inline uint32_t swaw32_hw(uint32_t value)
+{
+ /*
+ result[31..16] = value[15.. 0];
+ result[15.. 0] = value[31..16];
+ */
+ return (value >> 16) | (value << 16);
+}
+
#endif /* NEED_GENERIC_BYTESWAPS */
+/* static endianness conversion */
+#define SWAP16_CONST(x) \
+ ((typeof(x))( ((uint16_t)(x) >> 8) | ((uint16_t)(x) << 8) ))
+
+#define SWAP32_CONST(x) \
+ ((typeof(x))( ((uint32_t)(x) >> 24) | \
+ (((uint32_t)(x) & 0xff0000) >> 8) | \
+ (((uint32_t)(x) & 0xff00) << 8) | \
+ ((uint32_t)(x) << 24) ))
+
+#define SWAP_ODD_EVEN32_CONST(x) \
+ ((typeof(x))( ((uint32_t)SWAP16_CONST((uint32_t)(x) >> 16) << 16) | \
+ SWAP16_CONST((uint32_t)(x))) )
+
+#define SWAW32_CONST(x) \
+ ((typeof(x))( ((uint32_t)(x) << 16) | ((uint32_t)(x) >> 16) ))
+
+/* Select best method based upon whether x is a constant expression */
+#define swap16(x) \
+ ( __builtin_constant_p(x) ? SWAP16_CONST(x) : (typeof(x))swap16_hw(x) )
+
+#define swap32(x) \
+ ( __builtin_constant_p(x) ? SWAP32_CONST(x) : (typeof(x))swap32_hw(x) )
+
+#define swap_odd_even32(x) \
+ ( __builtin_constant_p(x) ? SWAP_ODD_EVEN32_CONST(x) : (typeof(x))swap_odd_even32_hw(x) )
+
+#define swaw32(x) \
+ ( __builtin_constant_p(x) ? SWAW32_CONST(x) : (typeof(x))swaw32_hw(x) )
+
+
+#ifdef ROCKBOX_LITTLE_ENDIAN
+#define letoh16(x) (x)
+#define letoh32(x) (x)
+#define htole16(x) (x)
+#define htole32(x) (x)
+#define betoh16(x) swap16(x)
+#define betoh32(x) swap32(x)
+#define htobe16(x) swap16(x)
+#define htobe32(x) swap32(x)
+#define swap_odd_even_be32(x) (x)
+#define swap_odd_even_le32(x) swap_odd_even32(x)
+#else
+#define letoh16(x) swap16(x)
+#define letoh32(x) swap32(x)
+#define htole16(x) swap16(x)
+#define htole32(x) swap32(x)
+#define betoh16(x) (x)
+#define betoh32(x) (x)
+#define htobe16(x) (x)
+#define htobe32(x) (x)
+#define swap_odd_even_be32(x) swap_odd_even32(x)
+#define swap_odd_even_le32(x) (x)
+#endif
+
#ifndef BIT_N
#define BIT_N(n) (1U << (n))
#endif