|
@@ -3,7 +3,7 @@
|
|
|
|
|
|
#include <asm/types.h>
|
|
|
|
|
|
-extern int __bug_unaligned_x(void *ptr);
|
|
|
+extern int __bug_unaligned_x(const void *ptr);
|
|
|
|
|
|
/*
|
|
|
* What is the most efficient way of loading/storing an unaligned value?
|
|
@@ -51,44 +51,32 @@ extern int __bug_unaligned_x(void *ptr);
|
|
|
#define __get_unaligned_4_be(__p) \
|
|
|
(__p[0] << 24 | __p[1] << 16 | __p[2] << 8 | __p[3])
|
|
|
|
|
|
-#define __get_unaligned_le(ptr) \
|
|
|
- ({ \
|
|
|
- __typeof__(*(ptr)) __v; \
|
|
|
- __u8 *__p = (__u8 *)(ptr); \
|
|
|
- switch (sizeof(*(ptr))) { \
|
|
|
- case 1: __v = *(ptr); break; \
|
|
|
- case 2: __v = __get_unaligned_2_le(__p); break; \
|
|
|
- case 4: __v = __get_unaligned_4_le(__p); break; \
|
|
|
- case 8: { \
|
|
|
- unsigned int __v1, __v2; \
|
|
|
- __v2 = __get_unaligned_4_le((__p+4)); \
|
|
|
- __v1 = __get_unaligned_4_le(__p); \
|
|
|
- __v = ((unsigned long long)__v2 << 32 | __v1); \
|
|
|
- } \
|
|
|
- break; \
|
|
|
- default: __v = __bug_unaligned_x(__p); break; \
|
|
|
- } \
|
|
|
- __v; \
|
|
|
+#define __get_unaligned_8_le(__p) \
|
|
|
+ ((unsigned long long)__get_unaligned_4_le((__p+4)) << 32 | \
|
|
|
+ __get_unaligned_4_le(__p))
|
|
|
+
|
|
|
+#define __get_unaligned_8_be(__p) \
|
|
|
+ ((unsigned long long)__get_unaligned_4_be(__p) << 32 | \
|
|
|
+ __get_unaligned_4_be((__p+4)))
|
|
|
+
|
|
|
+#define __get_unaligned_le(ptr) \
|
|
|
+ ({ \
|
|
|
+ const __u8 *__p = (const __u8 *)(ptr); \
|
|
|
+ __builtin_choose_expr(sizeof(*(ptr)) == 1, *__p, \
|
|
|
+ __builtin_choose_expr(sizeof(*(ptr)) == 2, __get_unaligned_2_le(__p), \
|
|
|
+ __builtin_choose_expr(sizeof(*(ptr)) == 4, __get_unaligned_4_le(__p), \
|
|
|
+ __builtin_choose_expr(sizeof(*(ptr)) == 8, __get_unaligned_8_le(__p), \
|
|
|
+ (void)__bug_unaligned_x(__p))))); \
|
|
|
})
|
|
|
|
|
|
-#define __get_unaligned_be(ptr) \
|
|
|
- ({ \
|
|
|
- __typeof__(*(ptr)) __v; \
|
|
|
- __u8 *__p = (__u8 *)(ptr); \
|
|
|
- switch (sizeof(*(ptr))) { \
|
|
|
- case 1: __v = *(ptr); break; \
|
|
|
- case 2: __v = __get_unaligned_2_be(__p); break; \
|
|
|
- case 4: __v = __get_unaligned_4_be(__p); break; \
|
|
|
- case 8: { \
|
|
|
- unsigned int __v1, __v2; \
|
|
|
- __v2 = __get_unaligned_4_be(__p); \
|
|
|
- __v1 = __get_unaligned_4_be((__p+4)); \
|
|
|
- __v = ((unsigned long long)__v2 << 32 | __v1); \
|
|
|
- } \
|
|
|
- break; \
|
|
|
- default: __v = __bug_unaligned_x(__p); break; \
|
|
|
- } \
|
|
|
- __v; \
|
|
|
+#define __get_unaligned_be(ptr) \
|
|
|
+ ({ \
|
|
|
+ const __u8 *__p = (const __u8 *)(ptr); \
|
|
|
+ __builtin_choose_expr(sizeof(*(ptr)) == 1, *__p, \
|
|
|
+ __builtin_choose_expr(sizeof(*(ptr)) == 2, __get_unaligned_2_be(__p), \
|
|
|
+ __builtin_choose_expr(sizeof(*(ptr)) == 4, __get_unaligned_4_be(__p), \
|
|
|
+ __builtin_choose_expr(sizeof(*(ptr)) == 8, __get_unaligned_8_be(__p), \
|
|
|
+ (void)__bug_unaligned_x(__p))))); \
|
|
|
})
|
|
|
|
|
|
|