summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Turner <mattst88@gmail.com>2011-08-16 19:19:24 -0400
committerMatt Turner <mattst88@gmail.com>2011-09-21 17:14:44 -0400
commitd206d52f657cb63a0f6ba8b62d788c1812b57c81 (patch)
tree3900247bd0015d1b3f1059b6aefa5ba5eb0084f0
parent889b700e7760ced38bcf5f3aff2d31d3d9a058d7 (diff)
Use __builtin_constant_p to determine if we can use lswapl
If the address of the swapped memory location is known at compile time, we can check its alignment at no runtime cost and use lswapl instead. text data bss dec hex filename before: 1872820 52136 78040 2002996 1e9034 hw/xfree86/Xorg after: 1864396 52136 78040 1994572 1e6f4c hw/xfree86/Xorg bswap instructions: 131 -> 308 (used in lswapl) rol instructions: 943 -> 1174 (used in lswaps) Reviewed-by: Peter Harris <pharris@opentext.com> Signed-off-by: Matt Turner <mattst88@gmail.com>
-rw-r--r--include/misc.h15
1 files changed, 13 insertions, 2 deletions
diff --git a/include/misc.h b/include/misc.h
index fb235edeb..1fea73ec3 100644
--- a/include/misc.h
+++ b/include/misc.h
@@ -267,6 +267,11 @@ void __attribute__((error("wrong sized variable passed to swap"))) wrong_size(vo
static inline void wrong_size(void)
{
}
+
+static inline void __builtin_constant_p(int x)
+{
+ return 0;
+}
#endif
/* byte swap a 32-bit value */
@@ -283,7 +288,10 @@ static inline void swap_uint32(uint32_t *x)
#define swapl(x) do { \
if (sizeof(*(x)) != 4) \
wrong_size(); \
- swap_uint32((uint32_t *)(x)); \
+ if (__builtin_constant_p((uintptr_t)(x) & 3) && ((uintptr_t)(x) & 3) == 0) \
+ *(x) = lswapl(*(x)); \
+ else \
+ swap_uint32((uint32_t *)(x)); \
} while (0)
/* byte swap a 16-bit value */
@@ -297,7 +305,10 @@ static inline void swap_uint16(uint16_t *x)
#define swaps(x) do { \
if (sizeof(*(x)) != 2) \
wrong_size(); \
- swap_uint16((uint16_t *)(x)); \
+ if (__builtin_constant_p((uintptr_t)(x) & 1) && ((uintptr_t)(x) & 1) == 0) \
+ *(x) = lswaps(*(x)); \
+ else \
+ swap_uint16((uint16_t *)(x)); \
} while (0)
/* copy 32-bit value from src to dst byteswapping on the way */