diff options
Diffstat (limited to 'include')
24 files changed, 201 insertions, 893 deletions
diff --git a/include/asm-alpha/unaligned.h b/include/asm-alpha/unaligned.h index a1d72846f61..3787c60aed3 100644 --- a/include/asm-alpha/unaligned.h +++ b/include/asm-alpha/unaligned.h | |||
| @@ -1,6 +1,11 @@ | |||
| 1 | #ifndef __ALPHA_UNALIGNED_H | 1 | #ifndef _ASM_ALPHA_UNALIGNED_H |
| 2 | #define __ALPHA_UNALIGNED_H | 2 | #define _ASM_ALPHA_UNALIGNED_H |
| 3 | 3 | ||
| 4 | #include <asm-generic/unaligned.h> | 4 | #include <linux/unaligned/le_struct.h> |
| 5 | #include <linux/unaligned/be_byteshift.h> | ||
| 6 | #include <linux/unaligned/generic.h> | ||
| 5 | 7 | ||
| 6 | #endif | 8 | #define get_unaligned __get_unaligned_le |
| 9 | #define put_unaligned __put_unaligned_le | ||
| 10 | |||
| 11 | #endif /* _ASM_ALPHA_UNALIGNED_H */ | ||
diff --git a/include/asm-arm/unaligned.h b/include/asm-arm/unaligned.h index 5db03cf3b90..44593a89490 100644 --- a/include/asm-arm/unaligned.h +++ b/include/asm-arm/unaligned.h | |||
| @@ -1,171 +1,9 @@ | |||
| 1 | #ifndef __ASM_ARM_UNALIGNED_H | 1 | #ifndef _ASM_ARM_UNALIGNED_H |
| 2 | #define __ASM_ARM_UNALIGNED_H | 2 | #define _ASM_ARM_UNALIGNED_H |
| 3 | 3 | ||
| 4 | #include <asm/types.h> | 4 | #include <linux/unaligned/le_byteshift.h> |
| 5 | 5 | #include <linux/unaligned/be_byteshift.h> | |
| 6 | extern int __bug_unaligned_x(const void *ptr); | 6 | #include <linux/unaligned/generic.h> |
| 7 | |||
| 8 | /* | ||
| 9 | * What is the most efficient way of loading/storing an unaligned value? | ||
| 10 | * | ||
| 11 | * That is the subject of this file. Efficiency here is defined as | ||
| 12 | * minimum code size with minimum register usage for the common cases. | ||
| 13 | * It is currently not believed that long longs are common, so we | ||
| 14 | * trade efficiency for the chars, shorts and longs against the long | ||
| 15 | * longs. | ||
| 16 | * | ||
| 17 | * Current stats with gcc 2.7.2.2 for these functions: | ||
| 18 | * | ||
| 19 | * ptrsize get: code regs put: code regs | ||
| 20 | * 1 1 1 1 2 | ||
| 21 | * 2 3 2 3 2 | ||
| 22 | * 4 7 3 7 3 | ||
| 23 | * 8 20 6 16 6 | ||
| 24 | * | ||
| 25 | * gcc 2.95.1 seems to code differently: | ||
| 26 | * | ||
| 27 | * ptrsize get: code regs put: code regs | ||
| 28 | * 1 1 1 1 2 | ||
| 29 | * 2 3 2 3 2 | ||
| 30 | * 4 7 4 7 4 | ||
| 31 | * 8 19 8 15 6 | ||
| 32 | * | ||
| 33 | * which may or may not be more efficient (depending upon whether | ||
| 34 | * you can afford the extra registers). Hopefully the gcc 2.95 | ||
| 35 | * is inteligent enough to decide if it is better to use the | ||
| 36 | * extra register, but evidence so far seems to suggest otherwise. | ||
| 37 | * | ||
| 38 | * Unfortunately, gcc is not able to optimise the high word | ||
| 39 | * out of long long >> 32, or the low word from long long << 32 | ||
| 40 | */ | ||
| 41 | |||
| 42 | #define __get_unaligned_2_le(__p) \ | ||
| 43 | (unsigned int)(__p[0] | __p[1] << 8) | ||
| 44 | |||
| 45 | #define __get_unaligned_2_be(__p) \ | ||
| 46 | (unsigned int)(__p[0] << 8 | __p[1]) | ||
| 47 | |||
| 48 | #define __get_unaligned_4_le(__p) \ | ||
| 49 | (unsigned int)(__p[0] | __p[1] << 8 | __p[2] << 16 | __p[3] << 24) | ||
| 50 | |||
| 51 | #define __get_unaligned_4_be(__p) \ | ||
| 52 | (unsigned int)(__p[0] << 24 | __p[1] << 16 | __p[2] << 8 | __p[3]) | ||
| 53 | |||
| 54 | #define __get_unaligned_8_le(__p) \ | ||
| 55 | ((unsigned long long)__get_unaligned_4_le((__p+4)) << 32 | \ | ||
| 56 | __get_unaligned_4_le(__p)) | ||
| 57 | |||
| 58 | #define __get_unaligned_8_be(__p) \ | ||
| 59 | ((unsigned long long)__get_unaligned_4_be(__p) << 32 | \ | ||
| 60 | __get_unaligned_4_be((__p+4))) | ||
| 61 | |||
| 62 | #define __get_unaligned_le(ptr) \ | ||
| 63 | ((__force typeof(*(ptr)))({ \ | ||
| 64 | const __u8 *__p = (const __u8 *)(ptr); \ | ||
| 65 | __builtin_choose_expr(sizeof(*(ptr)) == 1, *__p, \ | ||
| 66 | __builtin_choose_expr(sizeof(*(ptr)) == 2, __get_unaligned_2_le(__p), \ | ||
| 67 | __builtin_choose_expr(sizeof(*(ptr)) == 4, __get_unaligned_4_le(__p), \ | ||
| 68 | __builtin_choose_expr(sizeof(*(ptr)) == 8, __get_unaligned_8_le(__p), \ | ||
| 69 | (void)__bug_unaligned_x(__p))))); \ | ||
| 70 | })) | ||
| 71 | |||
| 72 | #define __get_unaligned_be(ptr) \ | ||
| 73 | ((__force typeof(*(ptr)))({ \ | ||
| 74 | const __u8 *__p = (const __u8 *)(ptr); \ | ||
| 75 | __builtin_choose_expr(sizeof(*(ptr)) == 1, *__p, \ | ||
| 76 | __builtin_choose_expr(sizeof(*(ptr)) == 2, __get_unaligned_2_be(__p), \ | ||
| 77 | __builtin_choose_expr(sizeof(*(ptr)) == 4, __get_unaligned_4_be(__p), \ | ||
| 78 | __builtin_choose_expr(sizeof(*(ptr)) == 8, __get_unaligned_8_be(__p), \ | ||
| 79 | (void)__bug_unaligned_x(__p))))); \ | ||
| 80 | })) | ||
| 81 | |||
| 82 | |||
| 83 | static inline void __put_unaligned_2_le(__u32 __v, register __u8 *__p) | ||
| 84 | { | ||
| 85 | *__p++ = __v; | ||
| 86 | *__p++ = __v >> 8; | ||
| 87 | } | ||
| 88 | |||
| 89 | static inline void __put_unaligned_2_be(__u32 __v, register __u8 *__p) | ||
| 90 | { | ||
| 91 | *__p++ = __v >> 8; | ||
| 92 | *__p++ = __v; | ||
| 93 | } | ||
| 94 | |||
| 95 | static inline void __put_unaligned_4_le(__u32 __v, register __u8 *__p) | ||
| 96 | { | ||
| 97 | __put_unaligned_2_le(__v >> 16, __p + 2); | ||
| 98 | __put_unaligned_2_le(__v, __p); | ||
| 99 | } | ||
| 100 | |||
| 101 | static inline void __put_unaligned_4_be(__u32 __v, register __u8 *__p) | ||
| 102 | { | ||
| 103 | __put_unaligned_2_be(__v >> 16, __p); | ||
| 104 | __put_unaligned_2_be(__v, __p + 2); | ||
| 105 | } | ||
| 106 | |||
| 107 | static inline void __put_unaligned_8_le(const unsigned long long __v, register __u8 *__p) | ||
| 108 | { | ||
| 109 | /* | ||
| 110 | * tradeoff: 8 bytes of stack for all unaligned puts (2 | ||
| 111 | * instructions), or an extra register in the long long | ||
| 112 | * case - go for the extra register. | ||
| 113 | */ | ||
| 114 | __put_unaligned_4_le(__v >> 32, __p+4); | ||
| 115 | __put_unaligned_4_le(__v, __p); | ||
| 116 | } | ||
| 117 | |||
| 118 | static inline void __put_unaligned_8_be(const unsigned long long __v, register __u8 *__p) | ||
| 119 | { | ||
| 120 | /* | ||
| 121 | * tradeoff: 8 bytes of stack for all unaligned puts (2 | ||
| 122 | * instructions), or an extra register in the long long | ||
| 123 | * case - go for the extra register. | ||
| 124 | */ | ||
| 125 | __put_unaligned_4_be(__v >> 32, __p); | ||
| 126 | __put_unaligned_4_be(__v, __p+4); | ||
| 127 | } | ||
| 128 | |||
| 129 | /* | ||
| 130 | * Try to store an unaligned value as efficiently as possible. | ||
| 131 | */ | ||
| 132 | #define __put_unaligned_le(val,ptr) \ | ||
| 133 | ({ \ | ||
| 134 | (void)sizeof(*(ptr) = (val)); \ | ||
| 135 | switch (sizeof(*(ptr))) { \ | ||
| 136 | case 1: \ | ||
| 137 | *(ptr) = (val); \ | ||
| 138 | break; \ | ||
| 139 | case 2: __put_unaligned_2_le((__force u16)(val),(__u8 *)(ptr)); \ | ||
| 140 | break; \ | ||
| 141 | case 4: __put_unaligned_4_le((__force u32)(val),(__u8 *)(ptr)); \ | ||
| 142 | break; \ | ||
| 143 | case 8: __put_unaligned_8_le((__force u64)(val),(__u8 *)(ptr)); \ | ||
| 144 | break; \ | ||
| 145 | default: __bug_unaligned_x(ptr); \ | ||
| 146 | break; \ | ||
| 147 | } \ | ||
| 148 | (void) 0; \ | ||
| 149 | }) | ||
| 150 | |||
| 151 | #define __put_unaligned_be(val,ptr) \ | ||
| 152 | ({ \ | ||
| 153 | (void)sizeof(*(ptr) = (val)); \ | ||
| 154 | switch (sizeof(*(ptr))) { \ | ||
| 155 | case 1: \ | ||
| 156 | *(ptr) = (val); \ | ||
| 157 | break; \ | ||
| 158 | case 2: __put_unaligned_2_be((__force u16)(val),(__u8 *)(ptr)); \ | ||
| 159 | break; \ | ||
| 160 | case 4: __put_unaligned_4_be((__force u32)(val),(__u8 *)(ptr)); \ | ||
| 161 | break; \ | ||
| 162 | case 8: __put_unaligned_8_be((__force u64)(val),(__u8 *)(ptr)); \ | ||
| 163 | break; \ | ||
| 164 | default: __bug_unaligned_x(ptr); \ | ||
| 165 | break; \ | ||
| 166 | } \ | ||
| 167 | (void) 0; \ | ||
| 168 | }) | ||
| 169 | 7 | ||
| 170 | /* | 8 | /* |
| 171 | * Select endianness | 9 | * Select endianness |
| @@ -178,4 +16,4 @@ static inline void __put_unaligned_8_be(const unsigned long long __v, register _ | |||
| 178 | #define put_unaligned __put_unaligned_be | 16 | #define put_unaligned __put_unaligned_be |
| 179 | #endif | 17 | #endif |
| 180 | 18 | ||
| 181 | #endif | 19 | #endif /* _ASM_ARM_UNALIGNED_H */ |
diff --git a/include/asm-avr32/unaligned.h b/include/asm-avr32/unaligned.h index 36f5fd43054..04187729047 100644 --- a/include/asm-avr32/unaligned.h +++ b/include/asm-avr32/unaligned.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | #ifndef __ASM_AVR32_UNALIGNED_H | 1 | #ifndef _ASM_AVR32_UNALIGNED_H |
| 2 | #define __ASM_AVR32_UNALIGNED_H | 2 | #define _ASM_AVR32_UNALIGNED_H |
| 3 | 3 | ||
| 4 | /* | 4 | /* |
| 5 | * AVR32 can handle some unaligned accesses, depending on the | 5 | * AVR32 can handle some unaligned accesses, depending on the |
| @@ -11,6 +11,11 @@ | |||
| 11 | * optimize word loads in general. | 11 | * optimize word loads in general. |
| 12 | */ | 12 | */ |
| 13 | 13 | ||
| 14 | #include <asm-generic/unaligned.h> | 14 | #include <linux/unaligned/be_struct.h> |
| 15 | #include <linux/unaligned/le_byteshift.h> | ||
| 16 | #include <linux/unaligned/generic.h> | ||
| 15 | 17 | ||
| 16 | #endif /* __ASM_AVR32_UNALIGNED_H */ | 18 | #define get_unaligned __get_unaligned_be |
| 19 | #define put_unaligned __put_unaligned_be | ||
| 20 | |||
| 21 | #endif /* _ASM_AVR32_UNALIGNED_H */ | ||
diff --git a/include/asm-blackfin/unaligned.h b/include/asm-blackfin/unaligned.h index 10081dc241e..fd8a1d63494 100644 --- a/include/asm-blackfin/unaligned.h +++ b/include/asm-blackfin/unaligned.h | |||
| @@ -1,6 +1,11 @@ | |||
| 1 | #ifndef __BFIN_UNALIGNED_H | 1 | #ifndef _ASM_BLACKFIN_UNALIGNED_H |
| 2 | #define __BFIN_UNALIGNED_H | 2 | #define _ASM_BLACKFIN_UNALIGNED_H |
| 3 | 3 | ||
| 4 | #include <asm-generic/unaligned.h> | 4 | #include <linux/unaligned/le_struct.h> |
| 5 | #include <linux/unaligned/be_byteshift.h> | ||
| 6 | #include <linux/unaligned/generic.h> | ||
| 5 | 7 | ||
| 6 | #endif /* __BFIN_UNALIGNED_H */ | 8 | #define get_unaligned __get_unaligned_le |
| 9 | #define put_unaligned __put_unaligned_le | ||
| 10 | |||
| 11 | #endif /* _ASM_BLACKFIN_UNALIGNED_H */ | ||
diff --git a/include/asm-cris/unaligned.h b/include/asm-cris/unaligned.h index 7fbbb399f6f..7b3f3fec567 100644 --- a/include/asm-cris/unaligned.h +++ b/include/asm-cris/unaligned.h | |||
| @@ -1,16 +1,13 @@ | |||
| 1 | #ifndef __CRIS_UNALIGNED_H | 1 | #ifndef _ASM_CRIS_UNALIGNED_H |
| 2 | #define __CRIS_UNALIGNED_H | 2 | #define _ASM_CRIS_UNALIGNED_H |
| 3 | 3 | ||
| 4 | /* | 4 | /* |
| 5 | * CRIS can do unaligned accesses itself. | 5 | * CRIS can do unaligned accesses itself. |
| 6 | * | ||
| 7 | * The strange macros are there to make sure these can't | ||
| 8 | * be misused in a way that makes them not work on other | ||
| 9 | * architectures where unaligned accesses aren't as simple. | ||
| 10 | */ | 6 | */ |
| 7 | #include <linux/unaligned/access_ok.h> | ||
| 8 | #include <linux/unaligned/generic.h> | ||
| 11 | 9 | ||
| 12 | #define get_unaligned(ptr) (*(ptr)) | 10 | #define get_unaligned __get_unaligned_le |
| 11 | #define put_unaligned __put_unaligned_le | ||
| 13 | 12 | ||
| 14 | #define put_unaligned(val, ptr) ((void)( *(ptr) = (val) )) | 13 | #endif /* _ASM_CRIS_UNALIGNED_H */ |
| 15 | |||
| 16 | #endif | ||
diff --git a/include/asm-frv/unaligned.h b/include/asm-frv/unaligned.h index dc8e9c9bf6b..64ccc736f2d 100644 --- a/include/asm-frv/unaligned.h +++ b/include/asm-frv/unaligned.h | |||
| @@ -9,194 +9,14 @@ | |||
| 9 | * 2 of the License, or (at your option) any later version. | 9 | * 2 of the License, or (at your option) any later version. |
| 10 | */ | 10 | */ |
| 11 | 11 | ||
| 12 | #ifndef _ASM_UNALIGNED_H | 12 | #ifndef _ASM_FRV_UNALIGNED_H |
| 13 | #define _ASM_UNALIGNED_H | 13 | #define _ASM_FRV_UNALIGNED_H |
| 14 | 14 | ||
| 15 | #include <linux/unaligned/le_byteshift.h> | ||
| 16 | #include <linux/unaligned/be_byteshift.h> | ||
| 17 | #include <linux/unaligned/generic.h> | ||
| 15 | 18 | ||
| 16 | /* | 19 | #define get_unaligned __get_unaligned_be |
| 17 | * Unaligned accesses on uClinux can't be performed in a fault handler - the | 20 | #define put_unaligned __put_unaligned_be |
| 18 | * CPU detects them as imprecise exceptions making this impossible. | ||
| 19 | * | ||
| 20 | * With the FR451, however, they are precise, and so we used to fix them up in | ||
| 21 | * the memory access fault handler. However, instruction bundling make this | ||
| 22 | * impractical. So, now we fall back to using memcpy. | ||
| 23 | */ | ||
| 24 | #ifdef CONFIG_MMU | ||
| 25 | |||
| 26 | /* | ||
| 27 | * The asm statement in the macros below is a way to get GCC to copy a | ||
| 28 | * value from one variable to another without having any clue it's | ||
| 29 | * actually doing so, so that it won't have any idea that the values | ||
| 30 | * in the two variables are related. | ||
| 31 | */ | ||
| 32 | |||
| 33 | #define get_unaligned(ptr) ({ \ | ||
| 34 | typeof((*(ptr))) __x; \ | ||
| 35 | void *__ptrcopy; \ | ||
| 36 | asm("" : "=r" (__ptrcopy) : "0" (ptr)); \ | ||
| 37 | memcpy(&__x, __ptrcopy, sizeof(*(ptr))); \ | ||
| 38 | __x; \ | ||
| 39 | }) | ||
| 40 | |||
| 41 | #define put_unaligned(val, ptr) ({ \ | ||
| 42 | typeof((*(ptr))) __x = (val); \ | ||
| 43 | void *__ptrcopy; \ | ||
| 44 | asm("" : "=r" (__ptrcopy) : "0" (ptr)); \ | ||
| 45 | memcpy(__ptrcopy, &__x, sizeof(*(ptr))); \ | ||
| 46 | }) | ||
| 47 | |||
| 48 | extern int handle_misalignment(unsigned long esr0, unsigned long ear0, unsigned long epcr0); | ||
| 49 | |||
| 50 | #else | ||
| 51 | |||
| 52 | #define get_unaligned(ptr) \ | ||
| 53 | ({ \ | ||
| 54 | typeof(*(ptr)) x; \ | ||
| 55 | const char *__p = (const char *) (ptr); \ | ||
| 56 | \ | ||
| 57 | switch (sizeof(x)) { \ | ||
| 58 | case 1: \ | ||
| 59 | x = *(ptr); \ | ||
| 60 | break; \ | ||
| 61 | case 2: \ | ||
| 62 | { \ | ||
| 63 | uint8_t a; \ | ||
| 64 | asm(" ldub%I2 %M2,%0 \n" \ | ||
| 65 | " ldub%I3.p %M3,%1 \n" \ | ||
| 66 | " slli %0,#8,%0 \n" \ | ||
| 67 | " or %0,%1,%0 \n" \ | ||
| 68 | : "=&r"(x), "=&r"(a) \ | ||
| 69 | : "m"(__p[0]), "m"(__p[1]) \ | ||
| 70 | ); \ | ||
| 71 | break; \ | ||
| 72 | } \ | ||
| 73 | \ | ||
| 74 | case 4: \ | ||
| 75 | { \ | ||
| 76 | uint8_t a; \ | ||
| 77 | asm(" ldub%I2 %M2,%0 \n" \ | ||
| 78 | " ldub%I3.p %M3,%1 \n" \ | ||
| 79 | " slli %0,#8,%0 \n" \ | ||
| 80 | " or %0,%1,%0 \n" \ | ||
| 81 | " ldub%I4.p %M4,%1 \n" \ | ||
| 82 | " slli %0,#8,%0 \n" \ | ||
| 83 | " or %0,%1,%0 \n" \ | ||
| 84 | " ldub%I5.p %M5,%1 \n" \ | ||
| 85 | " slli %0,#8,%0 \n" \ | ||
| 86 | " or %0,%1,%0 \n" \ | ||
| 87 | : "=&r"(x), "=&r"(a) \ | ||
| 88 | : "m"(__p[0]), "m"(__p[1]), "m"(__p[2]), "m"(__p[3]) \ | ||
| 89 | ); \ | ||
| 90 | break; \ | ||
| 91 | } \ | ||
| 92 | \ | ||
| 93 | case 8: \ | ||
| 94 | { \ | ||
| 95 | union { uint64_t x; u32 y[2]; } z; \ | ||
| 96 | uint8_t a; \ | ||
| 97 | asm(" ldub%I3 %M3,%0 \n" \ | ||
| 98 | " ldub%I4.p %M4,%2 \n" \ | ||
| 99 | " slli %0,#8,%0 \n" \ | ||
| 100 | " or %0,%2,%0 \n" \ | ||
| 101 | " ldub%I5.p %M5,%2 \n" \ | ||
| 102 | " slli %0,#8,%0 \n" \ | ||
| 103 | " or %0,%2,%0 \n" \ | ||
| 104 | " ldub%I6.p %M6,%2 \n" \ | ||
| 105 | " slli %0,#8,%0 \n" \ | ||
| 106 | " or %0,%2,%0 \n" \ | ||
| 107 | " ldub%I7 %M7,%1 \n" \ | ||
| 108 | " ldub%I8.p %M8,%2 \n" \ | ||
| 109 | " slli %1,#8,%1 \n" \ | ||
| 110 | " or %1,%2,%1 \n" \ | ||
| 111 | " ldub%I9.p %M9,%2 \n" \ | ||
| 112 | " slli %1,#8,%1 \n" \ | ||
| 113 | " or %1,%2,%1 \n" \ | ||
| 114 | " ldub%I10.p %M10,%2 \n" \ | ||
| 115 | " slli %1,#8,%1 \n" \ | ||
| 116 | " or %1,%2,%1 \n" \ | ||
| 117 | : "=&r"(z.y[0]), "=&r"(z.y[1]), "=&r"(a) \ | ||
| 118 | : "m"(__p[0]), "m"(__p[1]), "m"(__p[2]), "m"(__p[3]), \ | ||
| 119 | "m"(__p[4]), "m"(__p[5]), "m"(__p[6]), "m"(__p[7]) \ | ||
| 120 | ); \ | ||
| 121 | x = z.x; \ | ||
| 122 | break; \ | ||
| 123 | } \ | ||
| 124 | \ | ||
| 125 | default: \ | ||
| 126 | x = 0; \ | ||
| 127 | BUG(); \ | ||
| 128 | break; \ | ||
| 129 | } \ | ||
| 130 | \ | ||
| 131 | x; \ | ||
| 132 | }) | ||
| 133 | |||
| 134 | #define put_unaligned(val, ptr) \ | ||
| 135 | do { \ | ||
| 136 | char *__p = (char *) (ptr); \ | ||
| 137 | int x; \ | ||
| 138 | \ | ||
| 139 | switch (sizeof(*ptr)) { \ | ||
| 140 | case 2: \ | ||
| 141 | { \ | ||
| 142 | asm(" stb%I1.p %0,%M1 \n" \ | ||
| 143 | " srli %0,#8,%0 \n" \ | ||
| 144 | " stb%I2 %0,%M2 \n" \ | ||
| 145 | : "=r"(x), "=m"(__p[1]), "=m"(__p[0]) \ | ||
| 146 | : "0"(val) \ | ||
| 147 | ); \ | ||
| 148 | break; \ | ||
| 149 | } \ | ||
| 150 | \ | ||
| 151 | case 4: \ | ||
| 152 | { \ | ||
| 153 | asm(" stb%I1.p %0,%M1 \n" \ | ||
| 154 | " srli %0,#8,%0 \n" \ | ||
| 155 | " stb%I2.p %0,%M2 \n" \ | ||
| 156 | " srli %0,#8,%0 \n" \ | ||
| 157 | " stb%I3.p %0,%M3 \n" \ | ||
| 158 | " srli %0,#8,%0 \n" \ | ||
| 159 | " stb%I4 %0,%M4 \n" \ | ||
| 160 | : "=r"(x), "=m"(__p[3]), "=m"(__p[2]), "=m"(__p[1]), "=m"(__p[0]) \ | ||
| 161 | : "0"(val) \ | ||
| 162 | ); \ | ||
| 163 | break; \ | ||
| 164 | } \ | ||
| 165 | \ | ||
| 166 | case 8: \ | ||
| 167 | { \ | ||
| 168 | uint32_t __high, __low; \ | ||
| 169 | __high = (uint64_t)val >> 32; \ | ||
| 170 | __low = val & 0xffffffff; \ | ||
| 171 | asm(" stb%I2.p %0,%M2 \n" \ | ||
| 172 | " srli %0,#8,%0 \n" \ | ||
| 173 | " stb%I3.p %0,%M3 \n" \ | ||
| 174 | " srli %0,#8,%0 \n" \ | ||
| 175 | " stb%I4.p %0,%M4 \n" \ | ||
| 176 | " srli %0,#8,%0 \n" \ | ||
| 177 | " stb%I5.p %0,%M5 \n" \ | ||
| 178 | " srli %0,#8,%0 \n" \ | ||
| 179 | " stb%I6.p %1,%M6 \n" \ | ||
| 180 | " srli %1,#8,%1 \n" \ | ||
| 181 | " stb%I7.p %1,%M7 \n" \ | ||
| 182 | " srli %1,#8,%1 \n" \ | ||
| 183 | " stb%I8.p %1,%M8 \n" \ | ||
| 184 | " srli %1,#8,%1 \n" \ | ||
| 185 | " stb%I9 %1,%M9 \n" \ | ||
| 186 | : "=&r"(__low), "=&r"(__high), "=m"(__p[7]), "=m"(__p[6]), \ | ||
| 187 | "=m"(__p[5]), "=m"(__p[4]), "=m"(__p[3]), "=m"(__p[2]), \ | ||
| 188 | "=m"(__p[1]), "=m"(__p[0]) \ | ||
| 189 | : "0"(__low), "1"(__high) \ | ||
| 190 | ); \ | ||
| 191 | break; \ | ||
| 192 | } \ | ||
| 193 | \ | ||
| 194 | default: \ | ||
| 195 | *(ptr) = (val); \ | ||
| 196 | break; \ | ||
| 197 | } \ | ||
| 198 | } while(0) | ||
| 199 | |||
| 200 | #endif | ||
| 201 | 21 | ||
| 202 | #endif | 22 | #endif /* _ASM_FRV_UNALIGNED_H */ |
diff --git a/include/asm-generic/unaligned.h b/include/asm-generic/unaligned.h deleted file mode 100644 index 2fe1b2e67f0..00000000000 --- a/include/asm-generic/unaligned.h +++ /dev/null | |||
| @@ -1,124 +0,0 @@ | |||
| 1 | #ifndef _ASM_GENERIC_UNALIGNED_H_ | ||
| 2 | #define _ASM_GENERIC_UNALIGNED_H_ | ||
| 3 | |||
| 4 | /* | ||
| 5 | * For the benefit of those who are trying to port Linux to another | ||
| 6 | * architecture, here are some C-language equivalents. | ||
| 7 | * | ||
| 8 | * This is based almost entirely upon Richard Henderson's | ||
| 9 | * asm-alpha/unaligned.h implementation. Some comments were | ||
| 10 | * taken from David Mosberger's asm-ia64/unaligned.h header. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include <linux/types.h> | ||
| 14 | |||
| 15 | /* | ||
| 16 | * The main single-value unaligned transfer routines. | ||
| 17 | */ | ||
| 18 | #define get_unaligned(ptr) \ | ||
| 19 | __get_unaligned((ptr), sizeof(*(ptr))) | ||
| 20 | #define put_unaligned(x,ptr) \ | ||
| 21 | ((void)sizeof(*(ptr)=(x)),\ | ||
| 22 | __put_unaligned((__force __u64)(x), (ptr), sizeof(*(ptr)))) | ||
| 23 | |||
| 24 | /* | ||
| 25 | * This function doesn't actually exist. The idea is that when | ||
| 26 | * someone uses the macros below with an unsupported size (datatype), | ||
| 27 | * the linker will alert us to the problem via an unresolved reference | ||
| 28 | * error. | ||
| 29 | */ | ||
| 30 | extern void bad_unaligned_access_length(void) __attribute__((noreturn)); | ||
| 31 | |||
| 32 | struct __una_u64 { __u64 x __attribute__((packed)); }; | ||
| 33 | struct __una_u32 { __u32 x __attribute__((packed)); }; | ||
| 34 | struct __una_u16 { __u16 x __attribute__((packed)); }; | ||
| 35 | |||
| 36 | /* | ||
| 37 | * Elemental unaligned loads | ||
| 38 | */ | ||
| 39 | |||
| 40 | static inline __u64 __uldq(const __u64 *addr) | ||
| 41 | { | ||
| 42 | const struct __una_u64 *ptr = (const struct __una_u64 *) addr; | ||
| 43 | return ptr->x; | ||
| 44 | } | ||
| 45 | |||
| 46 | static inline __u32 __uldl(const __u32 *addr) | ||
| 47 | { | ||
| 48 | const struct __una_u32 *ptr = (const struct __una_u32 *) addr; | ||
| 49 | return ptr->x; | ||
| 50 | } | ||
| 51 | |||
| 52 | static inline __u16 __uldw(const __u16 *addr) | ||
| 53 | { | ||
| 54 | const struct __una_u16 *ptr = (const struct __una_u16 *) addr; | ||
| 55 | return ptr->x; | ||
| 56 | } | ||
| 57 | |||
| 58 | /* | ||
| 59 | * Elemental unaligned stores | ||
| 60 | */ | ||
| 61 | |||
| 62 | static inline void __ustq(__u64 val, __u64 *addr) | ||
| 63 | { | ||
| 64 | struct __una_u64 *ptr = (struct __una_u64 *) addr; | ||
| 65 | ptr->x = val; | ||
| 66 | } | ||
| 67 | |||
| 68 | static inline void __ustl(__u32 val, __u32 *addr) | ||
| 69 | { | ||
| 70 | struct __una_u32 *ptr = (struct __una_u32 *) addr; | ||
| 71 | ptr->x = val; | ||
| 72 | } | ||
| 73 | |||
| 74 | static inline void __ustw(__u16 val, __u16 *addr) | ||
| 75 | { | ||
| 76 | struct __una_u16 *ptr = (struct __una_u16 *) addr; | ||
| 77 | ptr->x = val; | ||
| 78 | } | ||
| 79 | |||
| 80 | #define __get_unaligned(ptr, size) ({ \ | ||
| 81 | const void *__gu_p = ptr; \ | ||
| 82 | __u64 __val; \ | ||
| 83 | switch (size) { \ | ||
| 84 | case 1: \ | ||
| 85 | __val = *(const __u8 *)__gu_p; \ | ||
| 86 | break; \ | ||
| 87 | case 2: \ | ||
| 88 | __val = __uldw(__gu_p); \ | ||
| 89 | break; \ | ||
| 90 | case 4: \ | ||
| 91 | __val = __uldl(__gu_p); \ | ||
| 92 | break; \ | ||
| 93 | case 8: \ | ||
| 94 | __val = __uldq(__gu_p); \ | ||
| 95 | break; \ | ||
| 96 | default: \ | ||
| 97 | bad_unaligned_access_length(); \ | ||
| 98 | }; \ | ||
| 99 | (__force __typeof__(*(ptr)))__val; \ | ||
| 100 | }) | ||
| 101 | |||
| 102 | #define __put_unaligned(val, ptr, size) \ | ||
| 103 | ({ \ | ||
| 104 | void *__gu_p = ptr; \ | ||
| 105 | switch (size) { \ | ||
| 106 | case 1: \ | ||
| 107 | *(__u8 *)__gu_p = (__force __u8)val; \ | ||
| 108 | break; \ | ||
| 109 | case 2: \ | ||
| 110 | __ustw((__force __u16)val, __gu_p); \ | ||
| 111 | break; \ | ||
| 112 | case 4: \ | ||
| 113 | __ustl((__force __u32)val, __gu_p); \ | ||
| 114 | break; \ | ||
| 115 | case 8: \ | ||
| 116 | __ustq(val, __gu_p); \ | ||
| 117 | break; \ | ||
| 118 | default: \ | ||
| 119 | bad_unaligned_access_length(); \ | ||
| 120 | }; \ | ||
| 121 | (void)0; \ | ||
| 122 | }) | ||
| 123 | |||
| 124 | #endif /* _ASM_GENERIC_UNALIGNED_H */ | ||
diff --git a/include/asm-h8300/unaligned.h b/include/asm-h8300/unaligned.h index ffb67f47207..b8d06c70c2d 100644 --- a/include/asm-h8300/unaligned.h +++ b/include/asm-h8300/unaligned.h | |||
| @@ -1,15 +1,11 @@ | |||
| 1 | #ifndef __H8300_UNALIGNED_H | 1 | #ifndef _ASM_H8300_UNALIGNED_H |
| 2 | #define __H8300_UNALIGNED_H | 2 | #define _ASM_H8300_UNALIGNED_H |
| 3 | 3 | ||
| 4 | #include <linux/unaligned/be_memmove.h> | ||
| 5 | #include <linux/unaligned/le_byteshift.h> | ||
| 6 | #include <linux/unaligned/generic.h> | ||
| 4 | 7 | ||
| 5 | /* Use memmove here, so gcc does not insert a __builtin_memcpy. */ | 8 | #define get_unaligned __get_unaligned_be |
| 9 | #define put_unaligned __put_unaligned_be | ||
| 6 | 10 | ||
| 7 | #define get_unaligned(ptr) \ | 11 | #endif /* _ASM_H8300_UNALIGNED_H */ |
| 8 | ({ __typeof__(*(ptr)) __tmp; memmove(&__tmp, (ptr), sizeof(*(ptr))); __tmp; }) | ||
| 9 | |||
| 10 | #define put_unaligned(val, ptr) \ | ||
| 11 | ({ __typeof__(*(ptr)) __tmp = (val); \ | ||
| 12 | memmove((ptr), &__tmp, sizeof(*(ptr))); \ | ||
| 13 | (void)0; }) | ||
| 14 | |||
| 15 | #endif | ||
diff --git a/include/asm-ia64/unaligned.h b/include/asm-ia64/unaligned.h index bb855988810..7bddc7f5858 100644 --- a/include/asm-ia64/unaligned.h +++ b/include/asm-ia64/unaligned.h | |||
| @@ -1,6 +1,11 @@ | |||
| 1 | #ifndef _ASM_IA64_UNALIGNED_H | 1 | #ifndef _ASM_IA64_UNALIGNED_H |
| 2 | #define _ASM_IA64_UNALIGNED_H | 2 | #define _ASM_IA64_UNALIGNED_H |
| 3 | 3 | ||
| 4 | #include <asm-generic/unaligned.h> | 4 | #include <linux/unaligned/le_struct.h> |
| 5 | #include <linux/unaligned/be_byteshift.h> | ||
| 6 | #include <linux/unaligned/generic.h> | ||
| 7 | |||
| 8 | #define get_unaligned __get_unaligned_le | ||
| 9 | #define put_unaligned __put_unaligned_le | ||
| 5 | 10 | ||
| 6 | #endif /* _ASM_IA64_UNALIGNED_H */ | 11 | #endif /* _ASM_IA64_UNALIGNED_H */ |
diff --git a/include/asm-m32r/unaligned.h b/include/asm-m32r/unaligned.h index fccc180c391..377eb20d1ec 100644 --- a/include/asm-m32r/unaligned.h +++ b/include/asm-m32r/unaligned.h | |||
| @@ -1,19 +1,18 @@ | |||
| 1 | #ifndef _ASM_M32R_UNALIGNED_H | 1 | #ifndef _ASM_M32R_UNALIGNED_H |
| 2 | #define _ASM_M32R_UNALIGNED_H | 2 | #define _ASM_M32R_UNALIGNED_H |
| 3 | 3 | ||
| 4 | /* | 4 | #if defined(__LITTLE_ENDIAN__) |
| 5 | * For the benefit of those who are trying to port Linux to another | 5 | # include <linux/unaligned/le_memmove.h> |
| 6 | * architecture, here are some C-language equivalents. | 6 | # include <linux/unaligned/be_byteshift.h> |
| 7 | */ | 7 | # include <linux/unaligned/generic.h> |
| 8 | 8 | # define get_unaligned __get_unaligned_le | |
| 9 | #include <asm/string.h> | 9 | # define put_unaligned __put_unaligned_le |
| 10 | 10 | #else | |
| 11 | #define get_unaligned(ptr) \ | 11 | # include <linux/unaligned/be_memmove.h> |
| 12 | ({ __typeof__(*(ptr)) __tmp; memmove(&__tmp, (ptr), sizeof(*(ptr))); __tmp; }) | 12 | # include <linux/unaligned/le_byteshift.h> |
| 13 | 13 | # include <linux/unaligned/generic.h> | |
| 14 | #define put_unaligned(val, ptr) \ | 14 | # define get_unaligned __get_unaligned_be |
| 15 | ({ __typeof__(*(ptr)) __tmp = (val); \ | 15 | # define put_unaligned __put_unaligned_be |
| 16 | memmove((ptr), &__tmp, sizeof(*(ptr))); \ | 16 | #endif |
| 17 | (void)0; }) | ||
| 18 | 17 | ||
| 19 | #endif /* _ASM_M32R_UNALIGNED_H */ | 18 | #endif /* _ASM_M32R_UNALIGNED_H */ |
diff --git a/include/asm-m68k/unaligned.h b/include/asm-m68k/unaligned.h index 804cb3f888f..77698f2dc33 100644 --- a/include/asm-m68k/unaligned.h +++ b/include/asm-m68k/unaligned.h | |||
| @@ -1,16 +1,13 @@ | |||
| 1 | #ifndef __M68K_UNALIGNED_H | 1 | #ifndef _ASM_M68K_UNALIGNED_H |
| 2 | #define __M68K_UNALIGNED_H | 2 | #define _ASM_M68K_UNALIGNED_H |
| 3 | 3 | ||
| 4 | /* | 4 | /* |
| 5 | * The m68k can do unaligned accesses itself. | 5 | * The m68k can do unaligned accesses itself. |
| 6 | * | ||
| 7 | * The strange macros are there to make sure these can't | ||
| 8 | * be misused in a way that makes them not work on other | ||
| 9 | * architectures where unaligned accesses aren't as simple. | ||
| 10 | */ | 6 | */ |
| 7 | #include <linux/unaligned/access_ok.h> | ||
| 8 | #include <linux/unaligned/generic.h> | ||
| 11 | 9 | ||
| 12 | #define get_unaligned(ptr) (*(ptr)) | 10 | #define get_unaligned __get_unaligned_be |
| 11 | #define put_unaligned __put_unaligned_be | ||
| 13 | 12 | ||
| 14 | #define put_unaligned(val, ptr) ((void)( *(ptr) = (val) )) | 13 | #endif /* _ASM_M68K_UNALIGNED_H */ |
| 15 | |||
| 16 | #endif | ||
diff --git a/include/asm-m68knommu/unaligned.h b/include/asm-m68knommu/unaligned.h index 869e9dd24f5..eb1ea4cb9a5 100644 --- a/include/asm-m68knommu/unaligned.h +++ b/include/asm-m68knommu/unaligned.h | |||
| @@ -1,23 +1,25 @@ | |||
| 1 | #ifndef __M68K_UNALIGNED_H | 1 | #ifndef _ASM_M68KNOMMU_UNALIGNED_H |
| 2 | #define __M68K_UNALIGNED_H | 2 | #define _ASM_M68KNOMMU_UNALIGNED_H |
| 3 | 3 | ||
| 4 | 4 | ||
| 5 | #ifdef CONFIG_COLDFIRE | 5 | #ifdef CONFIG_COLDFIRE |
| 6 | #include <linux/unaligned/be_struct.h> | ||
| 7 | #include <linux/unaligned/le_byteshift.h> | ||
| 8 | #include <linux/unaligned/generic.h> | ||
| 6 | 9 | ||
| 7 | #include <asm-generic/unaligned.h> | 10 | #define get_unaligned __get_unaligned_be |
| 11 | #define put_unaligned __put_unaligned_be | ||
| 8 | 12 | ||
| 9 | #else | 13 | #else |
| 10 | /* | 14 | /* |
| 11 | * The m68k can do unaligned accesses itself. | 15 | * The m68k can do unaligned accesses itself. |
| 12 | * | ||
| 13 | * The strange macros are there to make sure these can't | ||
| 14 | * be misused in a way that makes them not work on other | ||
| 15 | * architectures where unaligned accesses aren't as simple. | ||
| 16 | */ | 16 | */ |
| 17 | #include <linux/unaligned/access_ok.h> | ||
| 18 | #include <linux/unaligned/generic.h> | ||
| 17 | 19 | ||
| 18 | #define get_unaligned(ptr) (*(ptr)) | 20 | #define get_unaligned __get_unaligned_be |
| 19 | #define put_unaligned(val, ptr) ((void)( *(ptr) = (val) )) | 21 | #define put_unaligned __put_unaligned_be |
| 20 | 22 | ||
| 21 | #endif | 23 | #endif |
| 22 | 24 | ||
| 23 | #endif | 25 | #endif /* _ASM_M68KNOMMU_UNALIGNED_H */ |
diff --git a/include/asm-mips/unaligned.h b/include/asm-mips/unaligned.h index 3249049e93a..79240494857 100644 --- a/include/asm-mips/unaligned.h +++ b/include/asm-mips/unaligned.h | |||
| @@ -5,25 +5,24 @@ | |||
| 5 | * | 5 | * |
| 6 | * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org) | 6 | * Copyright (C) 2007 Ralf Baechle (ralf@linux-mips.org) |
| 7 | */ | 7 | */ |
| 8 | #ifndef __ASM_GENERIC_UNALIGNED_H | 8 | #ifndef _ASM_MIPS_UNALIGNED_H |
| 9 | #define __ASM_GENERIC_UNALIGNED_H | 9 | #define _ASM_MIPS_UNALIGNED_H |
| 10 | 10 | ||
| 11 | #include <linux/compiler.h> | 11 | #include <linux/compiler.h> |
| 12 | #if defined(__MIPSEB__) | ||
| 13 | # include <linux/unaligned/be_struct.h> | ||
| 14 | # include <linux/unaligned/le_byteshift.h> | ||
| 15 | # include <linux/unaligned/generic.h> | ||
| 16 | # define get_unaligned __get_unaligned_be | ||
| 17 | # define put_unaligned __put_unaligned_be | ||
| 18 | #elif defined(__MIPSEL__) | ||
| 19 | # include <linux/unaligned/le_struct.h> | ||
| 20 | # include <linux/unaligned/be_byteshift.h> | ||
| 21 | # include <linux/unaligned/generic.h> | ||
| 22 | # define get_unaligned __get_unaligned_le | ||
| 23 | # define put_unaligned __put_unaligned_le | ||
| 24 | #else | ||
| 25 | # error "MIPS, but neither __MIPSEB__, nor __MIPSEL__???" | ||
| 26 | #endif | ||
| 12 | 27 | ||
| 13 | #define get_unaligned(ptr) \ | 28 | #endif /* _ASM_MIPS_UNALIGNED_H */ |
| 14 | ({ \ | ||
| 15 | struct __packed { \ | ||
| 16 | typeof(*(ptr)) __v; \ | ||
| 17 | } *__p = (void *) (ptr); \ | ||
| 18 | __p->__v; \ | ||
| 19 | }) | ||
| 20 | |||
| 21 | #define put_unaligned(val, ptr) \ | ||
| 22 | do { \ | ||
| 23 | struct __packed { \ | ||
| 24 | typeof(*(ptr)) __v; \ | ||
| 25 | } *__p = (void *) (ptr); \ | ||
| 26 | __p->__v = (val); \ | ||
| 27 | } while(0) | ||
| 28 | |||
| 29 | #endif /* __ASM_GENERIC_UNALIGNED_H */ | ||
diff --git a/include/asm-mn10300/unaligned.h b/include/asm-mn10300/unaligned.h index cad3afbd035..0df671318ae 100644 --- a/include/asm-mn10300/unaligned.h +++ b/include/asm-mn10300/unaligned.h | |||
| @@ -8,129 +8,13 @@ | |||
| 8 | * as published by the Free Software Foundation; either version | 8 | * as published by the Free Software Foundation; either version |
| 9 | * 2 of the Licence, or (at your option) any later version. | 9 | * 2 of the Licence, or (at your option) any later version. |
| 10 | */ | 10 | */ |
| 11 | #ifndef _ASM_UNALIGNED_H | 11 | #ifndef _ASM_MN10300_UNALIGNED_H |
| 12 | #define _ASM_UNALIGNED_H | 12 | #define _ASM_MN10300_UNALIGNED_H |
| 13 | 13 | ||
| 14 | #include <asm/types.h> | 14 | #include <linux/unaligned/access_ok.h> |
| 15 | #include <linux/unaligned/generic.h> | ||
| 15 | 16 | ||
| 16 | #if 0 | 17 | #define get_unaligned __get_unaligned_le |
| 17 | extern int __bug_unaligned_x(void *ptr); | 18 | #define put_unaligned __put_unaligned_le |
| 18 | 19 | ||
| 19 | /* | 20 | #endif /* _ASM_MN10300_UNALIGNED_H */ |
| 20 | * What is the most efficient way of loading/storing an unaligned value? | ||
| 21 | * | ||
| 22 | * That is the subject of this file. Efficiency here is defined as | ||
| 23 | * minimum code size with minimum register usage for the common cases. | ||
| 24 | * It is currently not believed that long longs are common, so we | ||
| 25 | * trade efficiency for the chars, shorts and longs against the long | ||
| 26 | * longs. | ||
| 27 | * | ||
| 28 | * Current stats with gcc 2.7.2.2 for these functions: | ||
| 29 | * | ||
| 30 | * ptrsize get: code regs put: code regs | ||
| 31 | * 1 1 1 1 2 | ||
| 32 | * 2 3 2 3 2 | ||
| 33 | * 4 7 3 7 3 | ||
| 34 | * 8 20 6 16 6 | ||
| 35 | * | ||
| 36 | * gcc 2.95.1 seems to code differently: | ||
| 37 | * | ||
| 38 | * ptrsize get: code regs put: code regs | ||
| 39 | * 1 1 1 1 2 | ||
| 40 | * 2 3 2 3 2 | ||
| 41 | * 4 7 4 7 4 | ||
| 42 | * 8 19 8 15 6 | ||
| 43 | * | ||
| 44 | * which may or may not be more efficient (depending upon whether | ||
| 45 | * you can afford the extra registers). Hopefully the gcc 2.95 | ||
| 46 | * is inteligent enough to decide if it is better to use the | ||
| 47 | * extra register, but evidence so far seems to suggest otherwise. | ||
| 48 | * | ||
| 49 | * Unfortunately, gcc is not able to optimise the high word | ||
| 50 | * out of long long >> 32, or the low word from long long << 32 | ||
| 51 | */ | ||
| 52 | |||
| 53 | #define __get_unaligned_2(__p) \ | ||
| 54 | (__p[0] | __p[1] << 8) | ||
| 55 | |||
| 56 | #define __get_unaligned_4(__p) \ | ||
| 57 | (__p[0] | __p[1] << 8 | __p[2] << 16 | __p[3] << 24) | ||
| 58 | |||
| 59 | #define get_unaligned(ptr) \ | ||
| 60 | ({ \ | ||
| 61 | unsigned int __v1, __v2; \ | ||
| 62 | __typeof__(*(ptr)) __v; \ | ||
| 63 | __u8 *__p = (__u8 *)(ptr); \ | ||
| 64 | \ | ||
| 65 | switch (sizeof(*(ptr))) { \ | ||
| 66 | case 1: __v = *(ptr); break; \ | ||
| 67 | case 2: __v = __get_unaligned_2(__p); break; \ | ||
| 68 | case 4: __v = __get_unaligned_4(__p); break; \ | ||
| 69 | case 8: \ | ||
| 70 | __v2 = __get_unaligned_4((__p+4)); \ | ||
| 71 | __v1 = __get_unaligned_4(__p); \ | ||
| 72 | __v = ((unsigned long long)__v2 << 32 | __v1); \ | ||
| 73 | break; \ | ||
| 74 | default: __v = __bug_unaligned_x(__p); break; \ | ||
| 75 | } \ | ||
| 76 | __v; \ | ||
| 77 | }) | ||
| 78 | |||
| 79 | |||
| 80 | static inline void __put_unaligned_2(__u32 __v, register __u8 *__p) | ||
| 81 | { | ||
| 82 | *__p++ = __v; | ||
| 83 | *__p++ = __v >> 8; | ||
| 84 | } | ||
| 85 | |||
| 86 | static inline void __put_unaligned_4(__u32 __v, register __u8 *__p) | ||
| 87 | { | ||
| 88 | __put_unaligned_2(__v >> 16, __p + 2); | ||
| 89 | __put_unaligned_2(__v, __p); | ||
| 90 | } | ||
| 91 | |||
| 92 | static inline void __put_unaligned_8(const unsigned long long __v, __u8 *__p) | ||
| 93 | { | ||
| 94 | /* | ||
| 95 | * tradeoff: 8 bytes of stack for all unaligned puts (2 | ||
| 96 | * instructions), or an extra register in the long long | ||
| 97 | * case - go for the extra register. | ||
| 98 | */ | ||
| 99 | __put_unaligned_4(__v >> 32, __p + 4); | ||
| 100 | __put_unaligned_4(__v, __p); | ||
| 101 | } | ||
| 102 | |||
| 103 | /* | ||
| 104 | * Try to store an unaligned value as efficiently as possible. | ||
| 105 | */ | ||
| 106 | #define put_unaligned(val, ptr) \ | ||
| 107 | ({ \ | ||
| 108 | switch (sizeof(*(ptr))) { \ | ||
| 109 | case 1: \ | ||
| 110 | *(ptr) = (val); \ | ||
| 111 | break; \ | ||
| 112 | case 2: \ | ||
| 113 | __put_unaligned_2((val), (__u8 *)(ptr)); \ | ||
| 114 | break; \ | ||
| 115 | case 4: \ | ||
| 116 | __put_unaligned_4((val), (__u8 *)(ptr)); \ | ||
| 117 | break; \ | ||
| 118 | case 8: \ | ||
| 119 | __put_unaligned_8((val), (__u8 *)(ptr)); \ | ||
| 120 | break; \ | ||
| 121 | default: \ | ||
| 122 | __bug_unaligned_x(ptr); \ | ||
| 123 | break; \ | ||
| 124 | } \ | ||
| 125 | (void) 0; \ | ||
| 126 | }) | ||
| 127 | |||
| 128 | |||
| 129 | #else | ||
| 130 | |||
| 131 | #define get_unaligned(ptr) (*(ptr)) | ||
| 132 | #define put_unaligned(val, ptr) ({ *(ptr) = (val); (void) 0; }) | ||
| 133 | |||
| 134 | #endif | ||
| 135 | |||
| 136 | #endif | ||
diff --git a/include/asm-parisc/unaligned.h b/include/asm-parisc/unaligned.h index 53c905838d9..dfc5d3321a5 100644 --- a/include/asm-parisc/unaligned.h +++ b/include/asm-parisc/unaligned.h | |||
| @@ -1,7 +1,11 @@ | |||
| 1 | #ifndef _ASM_PARISC_UNALIGNED_H_ | 1 | #ifndef _ASM_PARISC_UNALIGNED_H |
| 2 | #define _ASM_PARISC_UNALIGNED_H_ | 2 | #define _ASM_PARISC_UNALIGNED_H |
| 3 | 3 | ||
| 4 | #include <asm-generic/unaligned.h> | 4 | #include <linux/unaligned/be_struct.h> |
| 5 | #include <linux/unaligned/le_byteshift.h> | ||
| 6 | #include <linux/unaligned/generic.h> | ||
| 7 | #define get_unaligned __get_unaligned_be | ||
| 8 | #define put_unaligned __put_unaligned_be | ||
| 5 | 9 | ||
| 6 | #ifdef __KERNEL__ | 10 | #ifdef __KERNEL__ |
| 7 | struct pt_regs; | 11 | struct pt_regs; |
| @@ -9,4 +13,4 @@ void handle_unaligned(struct pt_regs *regs); | |||
| 9 | int check_unaligned(struct pt_regs *regs); | 13 | int check_unaligned(struct pt_regs *regs); |
| 10 | #endif | 14 | #endif |
| 11 | 15 | ||
| 12 | #endif /* _ASM_PARISC_UNALIGNED_H_ */ | 16 | #endif /* _ASM_PARISC_UNALIGNED_H */ |
diff --git a/include/asm-powerpc/unaligned.h b/include/asm-powerpc/unaligned.h index 6c95dfa2652..5f1b1e3c213 100644 --- a/include/asm-powerpc/unaligned.h +++ b/include/asm-powerpc/unaligned.h | |||
| @@ -5,15 +5,12 @@ | |||
| 5 | 5 | ||
| 6 | /* | 6 | /* |
| 7 | * The PowerPC can do unaligned accesses itself in big endian mode. | 7 | * The PowerPC can do unaligned accesses itself in big endian mode. |
| 8 | * | ||
| 9 | * The strange macros are there to make sure these can't | ||
| 10 | * be misused in a way that makes them not work on other | ||
| 11 | * architectures where unaligned accesses aren't as simple. | ||
| 12 | */ | 8 | */ |
| 9 | #include <linux/unaligned/access_ok.h> | ||
| 10 | #include <linux/unaligned/generic.h> | ||
| 13 | 11 | ||
| 14 | #define get_unaligned(ptr) (*(ptr)) | 12 | #define get_unaligned __get_unaligned_be |
| 15 | 13 | #define put_unaligned __put_unaligned_be | |
| 16 | #define put_unaligned(val, ptr) ((void)( *(ptr) = (val) )) | ||
| 17 | 14 | ||
| 18 | #endif /* __KERNEL__ */ | 15 | #endif /* __KERNEL__ */ |
| 19 | #endif /* _ASM_POWERPC_UNALIGNED_H */ | 16 | #endif /* _ASM_POWERPC_UNALIGNED_H */ |
diff --git a/include/asm-s390/unaligned.h b/include/asm-s390/unaligned.h index 8ee86dbedd1..da9627afe5d 100644 --- a/include/asm-s390/unaligned.h +++ b/include/asm-s390/unaligned.h | |||
| @@ -1,24 +1,13 @@ | |||
| 1 | /* | 1 | #ifndef _ASM_S390_UNALIGNED_H |
| 2 | * include/asm-s390/unaligned.h | 2 | #define _ASM_S390_UNALIGNED_H |
| 3 | * | ||
| 4 | * S390 version | ||
| 5 | * | ||
| 6 | * Derived from "include/asm-i386/unaligned.h" | ||
| 7 | */ | ||
| 8 | |||
| 9 | #ifndef __S390_UNALIGNED_H | ||
| 10 | #define __S390_UNALIGNED_H | ||
| 11 | 3 | ||
| 12 | /* | 4 | /* |
| 13 | * The S390 can do unaligned accesses itself. | 5 | * The S390 can do unaligned accesses itself. |
| 14 | * | ||
| 15 | * The strange macros are there to make sure these can't | ||
| 16 | * be misused in a way that makes them not work on other | ||
| 17 | * architectures where unaligned accesses aren't as simple. | ||
| 18 | */ | 6 | */ |
| 7 | #include <linux/unaligned/access_ok.h> | ||
| 8 | #include <linux/unaligned/generic.h> | ||
| 19 | 9 | ||
| 20 | #define get_unaligned(ptr) (*(ptr)) | 10 | #define get_unaligned __get_unaligned_be |
| 21 | 11 | #define put_unaligned __put_unaligned_be | |
| 22 | #define put_unaligned(val, ptr) ((void)( *(ptr) = (val) )) | ||
| 23 | 12 | ||
| 24 | #endif | 13 | #endif /* _ASM_S390_UNALIGNED_H */ |
diff --git a/include/asm-sh/unaligned.h b/include/asm-sh/unaligned.h index 5250e3063b4..c1641a01d50 100644 --- a/include/asm-sh/unaligned.h +++ b/include/asm-sh/unaligned.h | |||
| @@ -1,7 +1,19 @@ | |||
| 1 | #ifndef __ASM_SH_UNALIGNED_H | 1 | #ifndef _ASM_SH_UNALIGNED_H |
| 2 | #define __ASM_SH_UNALIGNED_H | 2 | #define _ASM_SH_UNALIGNED_H |
| 3 | 3 | ||
| 4 | /* SH can't handle unaligned accesses. */ | 4 | /* SH can't handle unaligned accesses. */ |
| 5 | #include <asm-generic/unaligned.h> | 5 | #ifdef __LITTLE_ENDIAN__ |
| 6 | # include <linux/unaligned/le_struct.h> | ||
| 7 | # include <linux/unaligned/be_byteshift.h> | ||
| 8 | # include <linux/unaligned/generic.h> | ||
| 9 | # define get_unaligned __get_unaligned_le | ||
| 10 | # define put_unaligned __put_unaligned_le | ||
| 11 | #else | ||
| 12 | # include <linux/unaligned/be_struct.h> | ||
| 13 | # include <linux/unaligned/le_byteshift.h> | ||
| 14 | # include <linux/unaligned/generic.h> | ||
| 15 | # define get_unaligned __get_unaligned_be | ||
| 16 | # define put_unaligned __put_unaligned_be | ||
| 17 | #endif | ||
| 6 | 18 | ||
| 7 | #endif /* __ASM_SH_UNALIGNED_H */ | 19 | #endif /* _ASM_SH_UNALIGNED_H */ |
diff --git a/include/asm-sparc/unaligned.h b/include/asm-sparc/unaligned.h index b6f8eddd30a..11d2d5fb590 100644 --- a/include/asm-sparc/unaligned.h +++ b/include/asm-sparc/unaligned.h | |||
| @@ -1,6 +1,10 @@ | |||
| 1 | #ifndef _ASM_SPARC_UNALIGNED_H_ | 1 | #ifndef _ASM_SPARC_UNALIGNED_H |
| 2 | #define _ASM_SPARC_UNALIGNED_H_ | 2 | #define _ASM_SPARC_UNALIGNED_H |
| 3 | 3 | ||
| 4 | #include <asm-generic/unaligned.h> | 4 | #include <linux/unaligned/be_struct.h> |
| 5 | #include <linux/unaligned/le_byteshift.h> | ||
| 6 | #include <linux/unaligned/generic.h> | ||
| 7 | #define get_unaligned __get_unaligned_be | ||
| 8 | #define put_unaligned __put_unaligned_be | ||
| 5 | 9 | ||
| 6 | #endif /* _ASM_SPARC_UNALIGNED_H */ | 10 | #endif /* _ASM_SPARC_UNALIGNED_H */ |
diff --git a/include/asm-sparc64/unaligned.h b/include/asm-sparc64/unaligned.h index 1ed3ba53777..edcebb09441 100644 --- a/include/asm-sparc64/unaligned.h +++ b/include/asm-sparc64/unaligned.h | |||
| @@ -1,6 +1,10 @@ | |||
| 1 | #ifndef _ASM_SPARC64_UNALIGNED_H_ | 1 | #ifndef _ASM_SPARC64_UNALIGNED_H |
| 2 | #define _ASM_SPARC64_UNALIGNED_H_ | 2 | #define _ASM_SPARC64_UNALIGNED_H |
| 3 | 3 | ||
| 4 | #include <asm-generic/unaligned.h> | 4 | #include <linux/unaligned/be_struct.h> |
| 5 | #include <linux/unaligned/le_byteshift.h> | ||
| 6 | #include <linux/unaligned/generic.h> | ||
| 7 | #define get_unaligned __get_unaligned_be | ||
| 8 | #define put_unaligned __put_unaligned_be | ||
| 5 | 9 | ||
| 6 | #endif /* _ASM_SPARC64_UNALIGNED_H */ | 10 | #endif /* _ASM_SPARC64_UNALIGNED_H */ |
diff --git a/include/asm-um/unaligned.h b/include/asm-um/unaligned.h index 1d2497c5727..a47196974e3 100644 --- a/include/asm-um/unaligned.h +++ b/include/asm-um/unaligned.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | #ifndef __UM_UNALIGNED_H | 1 | #ifndef _ASM_UM_UNALIGNED_H |
| 2 | #define __UM_UNALIGNED_H | 2 | #define _ASM_UM_UNALIGNED_H |
| 3 | 3 | ||
| 4 | #include "asm/arch/unaligned.h" | 4 | #include "asm/arch/unaligned.h" |
| 5 | 5 | ||
| 6 | #endif | 6 | #endif /* _ASM_UM_UNALIGNED_H */ |
diff --git a/include/asm-v850/unaligned.h b/include/asm-v850/unaligned.h index e30b18653a9..53122b28491 100644 --- a/include/asm-v850/unaligned.h +++ b/include/asm-v850/unaligned.h | |||
| @@ -1,6 +1,4 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * include/asm-v850/unaligned.h -- Unaligned memory access | ||
| 3 | * | ||
| 4 | * Copyright (C) 2001 NEC Corporation | 2 | * Copyright (C) 2001 NEC Corporation |
| 5 | * Copyright (C) 2001 Miles Bader <miles@gnu.org> | 3 | * Copyright (C) 2001 Miles Bader <miles@gnu.org> |
| 6 | * | 4 | * |
| @@ -8,123 +6,17 @@ | |||
| 8 | * Public License. See the file COPYING in the main directory of this | 6 | * Public License. See the file COPYING in the main directory of this |
| 9 | * archive for more details. | 7 | * archive for more details. |
| 10 | * | 8 | * |
| 11 | * This file is a copy of the arm version, include/asm-arm/unaligned.h | ||
| 12 | * | ||
| 13 | * Note that some v850 chips support unaligned access, but it seems too | 9 | * Note that some v850 chips support unaligned access, but it seems too |
| 14 | * annoying to use. | 10 | * annoying to use. |
| 15 | */ | 11 | */ |
| 12 | #ifndef _ASM_V850_UNALIGNED_H | ||
| 13 | #define _ASM_V850_UNALIGNED_H | ||
| 16 | 14 | ||
| 17 | #ifndef __V850_UNALIGNED_H__ | 15 | #include <linux/unaligned/be_byteshift.h> |
| 18 | #define __V850_UNALIGNED_H__ | 16 | #include <linux/unaligned/le_byteshift.h> |
| 19 | 17 | #include <linux/unaligned/generic.h> | |
| 20 | #include <asm/types.h> | ||
| 21 | |||
| 22 | extern int __bug_unaligned_x(void *ptr); | ||
| 23 | |||
| 24 | /* | ||
| 25 | * What is the most efficient way of loading/storing an unaligned value? | ||
| 26 | * | ||
| 27 | * That is the subject of this file. Efficiency here is defined as | ||
| 28 | * minimum code size with minimum register usage for the common cases. | ||
| 29 | * It is currently not believed that long longs are common, so we | ||
| 30 | * trade efficiency for the chars, shorts and longs against the long | ||
| 31 | * longs. | ||
| 32 | * | ||
| 33 | * Current stats with gcc 2.7.2.2 for these functions: | ||
| 34 | * | ||
| 35 | * ptrsize get: code regs put: code regs | ||
| 36 | * 1 1 1 1 2 | ||
| 37 | * 2 3 2 3 2 | ||
| 38 | * 4 7 3 7 3 | ||
| 39 | * 8 20 6 16 6 | ||
| 40 | * | ||
| 41 | * gcc 2.95.1 seems to code differently: | ||
| 42 | * | ||
| 43 | * ptrsize get: code regs put: code regs | ||
| 44 | * 1 1 1 1 2 | ||
| 45 | * 2 3 2 3 2 | ||
| 46 | * 4 7 4 7 4 | ||
| 47 | * 8 19 8 15 6 | ||
| 48 | * | ||
| 49 | * which may or may not be more efficient (depending upon whether | ||
| 50 | * you can afford the extra registers). Hopefully the gcc 2.95 | ||
| 51 | * is inteligent enough to decide if it is better to use the | ||
| 52 | * extra register, but evidence so far seems to suggest otherwise. | ||
| 53 | * | ||
| 54 | * Unfortunately, gcc is not able to optimise the high word | ||
| 55 | * out of long long >> 32, or the low word from long long << 32 | ||
| 56 | */ | ||
| 57 | |||
| 58 | #define __get_unaligned_2(__p) \ | ||
| 59 | (__p[0] | __p[1] << 8) | ||
| 60 | |||
| 61 | #define __get_unaligned_4(__p) \ | ||
| 62 | (__p[0] | __p[1] << 8 | __p[2] << 16 | __p[3] << 24) | ||
| 63 | |||
| 64 | #define get_unaligned(ptr) \ | ||
| 65 | ({ \ | ||
| 66 | __typeof__(*(ptr)) __v; \ | ||
| 67 | __u8 *__p = (__u8 *)(ptr); \ | ||
| 68 | switch (sizeof(*(ptr))) { \ | ||
| 69 | case 1: __v = *(ptr); break; \ | ||
| 70 | case 2: __v = __get_unaligned_2(__p); break; \ | ||
| 71 | case 4: __v = __get_unaligned_4(__p); break; \ | ||
| 72 | case 8: { \ | ||
| 73 | unsigned int __v1, __v2; \ | ||
| 74 | __v2 = __get_unaligned_4((__p+4)); \ | ||
| 75 | __v1 = __get_unaligned_4(__p); \ | ||
| 76 | __v = ((unsigned long long)__v2 << 32 | __v1); \ | ||
| 77 | } \ | ||
| 78 | break; \ | ||
| 79 | default: __v = __bug_unaligned_x(__p); break; \ | ||
| 80 | } \ | ||
| 81 | __v; \ | ||
| 82 | }) | ||
| 83 | |||
| 84 | |||
| 85 | static inline void __put_unaligned_2(__u32 __v, register __u8 *__p) | ||
| 86 | { | ||
| 87 | *__p++ = __v; | ||
| 88 | *__p++ = __v >> 8; | ||
| 89 | } | ||
| 90 | |||
| 91 | static inline void __put_unaligned_4(__u32 __v, register __u8 *__p) | ||
| 92 | { | ||
| 93 | __put_unaligned_2(__v >> 16, __p + 2); | ||
| 94 | __put_unaligned_2(__v, __p); | ||
| 95 | } | ||
| 96 | |||
| 97 | static inline void __put_unaligned_8(const unsigned long long __v, register __u8 *__p) | ||
| 98 | { | ||
| 99 | /* | ||
| 100 | * tradeoff: 8 bytes of stack for all unaligned puts (2 | ||
| 101 | * instructions), or an extra register in the long long | ||
| 102 | * case - go for the extra register. | ||
| 103 | */ | ||
| 104 | __put_unaligned_4(__v >> 32, __p+4); | ||
| 105 | __put_unaligned_4(__v, __p); | ||
| 106 | } | ||
| 107 | |||
| 108 | /* | ||
| 109 | * Try to store an unaligned value as efficiently as possible. | ||
| 110 | */ | ||
| 111 | #define put_unaligned(val,ptr) \ | ||
| 112 | ({ \ | ||
| 113 | switch (sizeof(*(ptr))) { \ | ||
| 114 | case 1: \ | ||
| 115 | *(ptr) = (val); \ | ||
| 116 | break; \ | ||
| 117 | case 2: __put_unaligned_2((val),(__u8 *)(ptr)); \ | ||
| 118 | break; \ | ||
| 119 | case 4: __put_unaligned_4((val),(__u8 *)(ptr)); \ | ||
| 120 | break; \ | ||
| 121 | case 8: __put_unaligned_8((val),(__u8 *)(ptr)); \ | ||
| 122 | break; \ | ||
| 123 | default: __bug_unaligned_x(ptr); \ | ||
| 124 | break; \ | ||
| 125 | } \ | ||
| 126 | (void) 0; \ | ||
| 127 | }) | ||
| 128 | 18 | ||
| 19 | #define get_unaligned __get_unaligned_le | ||
| 20 | #define put_unaligned __put_unaligned_le | ||
| 129 | 21 | ||
| 130 | #endif /* __V850_UNALIGNED_H__ */ | 22 | #endif /* _ASM_V850_UNALIGNED_H */ |
diff --git a/include/asm-x86/unaligned.h b/include/asm-x86/unaligned.h index d270ffe7275..a7bd416b476 100644 --- a/include/asm-x86/unaligned.h +++ b/include/asm-x86/unaligned.h | |||
| @@ -3,35 +3,12 @@ | |||
| 3 | 3 | ||
| 4 | /* | 4 | /* |
| 5 | * The x86 can do unaligned accesses itself. | 5 | * The x86 can do unaligned accesses itself. |
| 6 | * | ||
| 7 | * The strange macros are there to make sure these can't | ||
| 8 | * be misused in a way that makes them not work on other | ||
| 9 | * architectures where unaligned accesses aren't as simple. | ||
| 10 | */ | 6 | */ |
| 11 | 7 | ||
| 12 | /** | 8 | #include <linux/unaligned/access_ok.h> |
| 13 | * get_unaligned - get value from possibly mis-aligned location | 9 | #include <linux/unaligned/generic.h> |
| 14 | * @ptr: pointer to value | ||
| 15 | * | ||
| 16 | * This macro should be used for accessing values larger in size than | ||
| 17 | * single bytes at locations that are expected to be improperly aligned, | ||
| 18 | * e.g. retrieving a u16 value from a location not u16-aligned. | ||
| 19 | * | ||
| 20 | * Note that unaligned accesses can be very expensive on some architectures. | ||
| 21 | */ | ||
| 22 | #define get_unaligned(ptr) (*(ptr)) | ||
| 23 | 10 | ||
| 24 | /** | 11 | #define get_unaligned __get_unaligned_le |
| 25 | * put_unaligned - put value to a possibly mis-aligned location | 12 | #define put_unaligned __put_unaligned_le |
| 26 | * @val: value to place | ||
| 27 | * @ptr: pointer to location | ||
| 28 | * | ||
| 29 | * This macro should be used for placing values larger in size than | ||
| 30 | * single bytes at locations that are expected to be improperly aligned, | ||
| 31 | * e.g. writing a u16 value to a location not u16-aligned. | ||
| 32 | * | ||
| 33 | * Note that unaligned accesses can be very expensive on some architectures. | ||
| 34 | */ | ||
| 35 | #define put_unaligned(val, ptr) ((void)(*(ptr) = (val))) | ||
| 36 | 13 | ||
| 37 | #endif /* _ASM_X86_UNALIGNED_H */ | 14 | #endif /* _ASM_X86_UNALIGNED_H */ |
diff --git a/include/asm-xtensa/unaligned.h b/include/asm-xtensa/unaligned.h index 28220890d0a..8f3424fc5d1 100644 --- a/include/asm-xtensa/unaligned.h +++ b/include/asm-xtensa/unaligned.h | |||
| @@ -1,6 +1,4 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * include/asm-xtensa/unaligned.h | ||
| 3 | * | ||
| 4 | * Xtensa doesn't handle unaligned accesses efficiently. | 2 | * Xtensa doesn't handle unaligned accesses efficiently. |
| 5 | * | 3 | * |
| 6 | * This file is subject to the terms and conditions of the GNU General Public | 4 | * This file is subject to the terms and conditions of the GNU General Public |
| @@ -9,20 +7,23 @@ | |||
| 9 | * | 7 | * |
| 10 | * Copyright (C) 2001 - 2005 Tensilica Inc. | 8 | * Copyright (C) 2001 - 2005 Tensilica Inc. |
| 11 | */ | 9 | */ |
| 10 | #ifndef _ASM_XTENSA_UNALIGNED_H | ||
| 11 | #define _ASM_XTENSA_UNALIGNED_H | ||
| 12 | 12 | ||
| 13 | #ifndef _XTENSA_UNALIGNED_H | 13 | #ifdef __XTENSA_EL__ |
| 14 | #define _XTENSA_UNALIGNED_H | 14 | # include <linux/unaligned/le_memmove.h> |
| 15 | 15 | # include <linux/unaligned/be_byteshift.h> | |
| 16 | #include <linux/string.h> | 16 | # include <linux/unaligned/generic.h> |
| 17 | 17 | # define get_unaligned __get_unaligned_le | |
| 18 | /* Use memmove here, so gcc does not insert a __builtin_memcpy. */ | 18 | # define put_unaligned __put_unaligned_le |
| 19 | 19 | #elif defined(__XTENSA_EB__) | |
| 20 | #define get_unaligned(ptr) \ | 20 | # include <linux/unaligned/be_memmove.h> |
| 21 | ({ __typeof__(*(ptr)) __tmp; memmove(&__tmp, (ptr), sizeof(*(ptr))); __tmp; }) | 21 | # include <linux/unaligned/le_byteshift.h> |
| 22 | 22 | # include <linux/unaligned/generic.h> | |
| 23 | #define put_unaligned(val, ptr) \ | 23 | # define get_unaligned __get_unaligned_be |
| 24 | ({ __typeof__(*(ptr)) __tmp = (val); \ | 24 | # define put_unaligned __put_unaligned_be |
| 25 | memmove((ptr), &__tmp, sizeof(*(ptr))); \ | 25 | #else |
| 26 | (void)0; }) | 26 | # error processor byte order undefined! |
| 27 | #endif | ||
| 27 | 28 | ||
| 28 | #endif /* _XTENSA_UNALIGNED_H */ | 29 | #endif /* _ASM_XTENSA_UNALIGNED_H */ |
