Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] optimise 64bit unaligned access on 32bit kernel

I've rewriten Atushi's fix for the 64-bit put_unaligned on 32-bit systems
bug to generate more efficient code.

This case has buzilla URL http://bugzilla.kernel.org/show_bug.cgi?id=5138.

Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

Ralf Baechle and committed by
Linus Torvalds
eed74dfc 82a25b56

+6 -6
+6 -6
include/asm-generic/unaligned.h
··· 16 16 * The main single-value unaligned transfer routines. 17 17 */ 18 18 #define get_unaligned(ptr) \ 19 - ((__typeof__(*(ptr)))__get_unaligned((ptr), sizeof(*(ptr)))) 19 + __get_unaligned((ptr), sizeof(*(ptr))) 20 20 #define put_unaligned(x,ptr) \ 21 - __put_unaligned((unsigned long)(x), (ptr), sizeof(*(ptr))) 21 + __put_unaligned((__u64)(x), (ptr), sizeof(*(ptr))) 22 22 23 23 /* 24 24 * This function doesn't actually exist. The idea is that when ··· 36 36 * Elemental unaligned loads 37 37 */ 38 38 39 - static inline unsigned long __uldq(const __u64 *addr) 39 + static inline __u64 __uldq(const __u64 *addr) 40 40 { 41 41 const struct __una_u64 *ptr = (const struct __una_u64 *) addr; 42 42 return ptr->x; 43 43 } 44 44 45 - static inline unsigned long __uldl(const __u32 *addr) 45 + static inline __u32 __uldl(const __u32 *addr) 46 46 { 47 47 const struct __una_u32 *ptr = (const struct __una_u32 *) addr; 48 48 return ptr->x; 49 49 } 50 50 51 - static inline unsigned long __uldw(const __u16 *addr) 51 + static inline __u16 __uldw(const __u16 *addr) 52 52 { 53 53 const struct __una_u16 *ptr = (const struct __una_u16 *) addr; 54 54 return ptr->x; ··· 78 78 79 79 #define __get_unaligned(ptr, size) ({ \ 80 80 const void *__gu_p = ptr; \ 81 - unsigned long val; \ 81 + __typeof__(*(ptr)) val; \ 82 82 switch (size) { \ 83 83 case 1: \ 84 84 val = *(const __u8 *)__gu_p; \