Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 17b602b1 authored by Lennert Buytenhek's avatar Lennert Buytenhek Committed by Russell King
Browse files

[ARM] 3849/1: fix get_unaligned() for gcc >= 4.1



gcc 4.1's __typeof__ propagates 'const', which breaks get_unaligned().
Rewrite get_unaligned() not to use __typeof__.

Signed-off-by: default avatarLennert Buytenhek <buytenh@wantstofly.org>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 3b7a86c2
Loading
Loading
Loading
Loading
+25 −37
Original line number Diff line number Diff line
@@ -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_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)						\
	({								\
		__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;						\
		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;						\
		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)))));			\
	})