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 | ||
