diff options
Diffstat (limited to 'include/asm-arm/unaligned.h')
-rw-r--r-- | include/asm-arm/unaligned.h | 62 |
1 files changed, 25 insertions, 37 deletions
diff --git a/include/asm-arm/unaligned.h b/include/asm-arm/unaligned.h index 1b39c2f322c9..795b9e5b9e6a 100644 --- a/include/asm-arm/unaligned.h +++ b/include/asm-arm/unaligned.h | |||
@@ -3,7 +3,7 @@ | |||
3 | 3 | ||
4 | #include <asm/types.h> | 4 | #include <asm/types.h> |
5 | 5 | ||
6 | extern int __bug_unaligned_x(void *ptr); | 6 | extern int __bug_unaligned_x(const void *ptr); |
7 | 7 | ||
8 | /* | 8 | /* |
9 | * What is the most efficient way of loading/storing an unaligned value? | 9 | * What is the most efficient way of loading/storing an unaligned value? |
@@ -51,44 +51,32 @@ extern int __bug_unaligned_x(void *ptr); | |||
51 | #define __get_unaligned_4_be(__p) \ | 51 | #define __get_unaligned_4_be(__p) \ |
52 | (__p[0] << 24 | __p[1] << 16 | __p[2] << 8 | __p[3]) | 52 | (__p[0] << 24 | __p[1] << 16 | __p[2] << 8 | __p[3]) |
53 | 53 | ||
54 | #define __get_unaligned_le(ptr) \ | 54 | #define __get_unaligned_8_le(__p) \ |
55 | ({ \ | 55 | ((unsigned long long)__get_unaligned_4_le((__p+4)) << 32 | \ |
56 | __typeof__(*(ptr)) __v; \ | 56 | __get_unaligned_4_le(__p)) |
57 | __u8 *__p = (__u8 *)(ptr); \ | 57 | |
58 | switch (sizeof(*(ptr))) { \ | 58 | #define __get_unaligned_8_be(__p) \ |
59 | case 1: __v = *(ptr); break; \ | 59 | ((unsigned long long)__get_unaligned_4_be(__p) << 32 | \ |
60 | case 2: __v = __get_unaligned_2_le(__p); break; \ | 60 | __get_unaligned_4_be((__p+4))) |
61 | case 4: __v = __get_unaligned_4_le(__p); break; \ | 61 | |
62 | case 8: { \ | 62 | #define __get_unaligned_le(ptr) \ |
63 | unsigned int __v1, __v2; \ | 63 | ({ \ |
64 | __v2 = __get_unaligned_4_le((__p+4)); \ | 64 | const __u8 *__p = (const __u8 *)(ptr); \ |
65 | __v1 = __get_unaligned_4_le(__p); \ | 65 | __builtin_choose_expr(sizeof(*(ptr)) == 1, *__p, \ |
66 | __v = ((unsigned long long)__v2 << 32 | __v1); \ | 66 | __builtin_choose_expr(sizeof(*(ptr)) == 2, __get_unaligned_2_le(__p), \ |
67 | } \ | 67 | __builtin_choose_expr(sizeof(*(ptr)) == 4, __get_unaligned_4_le(__p), \ |
68 | break; \ | 68 | __builtin_choose_expr(sizeof(*(ptr)) == 8, __get_unaligned_8_le(__p), \ |
69 | default: __v = __bug_unaligned_x(__p); break; \ | 69 | (void)__bug_unaligned_x(__p))))); \ |
70 | } \ | ||
71 | __v; \ | ||
72 | }) | 70 | }) |
73 | 71 | ||
74 | #define __get_unaligned_be(ptr) \ | 72 | #define __get_unaligned_be(ptr) \ |
75 | ({ \ | 73 | ({ \ |
76 | __typeof__(*(ptr)) __v; \ | 74 | const __u8 *__p = (const __u8 *)(ptr); \ |
77 | __u8 *__p = (__u8 *)(ptr); \ | 75 | __builtin_choose_expr(sizeof(*(ptr)) == 1, *__p, \ |
78 | switch (sizeof(*(ptr))) { \ | 76 | __builtin_choose_expr(sizeof(*(ptr)) == 2, __get_unaligned_2_be(__p), \ |
79 | case 1: __v = *(ptr); break; \ | 77 | __builtin_choose_expr(sizeof(*(ptr)) == 4, __get_unaligned_4_be(__p), \ |
80 | case 2: __v = __get_unaligned_2_be(__p); break; \ | 78 | __builtin_choose_expr(sizeof(*(ptr)) == 8, __get_unaligned_8_be(__p), \ |
81 | case 4: __v = __get_unaligned_4_be(__p); break; \ | 79 | (void)__bug_unaligned_x(__p))))); \ |
82 | case 8: { \ | ||
83 | unsigned int __v1, __v2; \ | ||
84 | __v2 = __get_unaligned_4_be(__p); \ | ||
85 | __v1 = __get_unaligned_4_be((__p+4)); \ | ||
86 | __v = ((unsigned long long)__v2 << 32 | __v1); \ | ||
87 | } \ | ||
88 | break; \ | ||
89 | default: __v = __bug_unaligned_x(__p); break; \ | ||
90 | } \ | ||
91 | __v; \ | ||
92 | }) | 80 | }) |
93 | 81 | ||
94 | 82 | ||