• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef _LINUX_UNALIGNED_GENERIC_H
2 #define _LINUX_UNALIGNED_GENERIC_H
3 
4 /*
5  * Cause a link-time error if we try an unaligned access other than
6  * 1,2,4 or 8 bytes long
7  */
8 extern void __bad_unaligned_access_size(void);
9 
10 #define __get_unaligned_le(ptr) ((__force typeof(*(ptr)))({			\
11 	__builtin_choose_expr(sizeof(*(ptr)) == 1, *(ptr),			\
12 	__builtin_choose_expr(sizeof(*(ptr)) == 2, get_unaligned_le16((ptr)),	\
13 	__builtin_choose_expr(sizeof(*(ptr)) == 4, get_unaligned_le32((ptr)),	\
14 	__builtin_choose_expr(sizeof(*(ptr)) == 8, get_unaligned_le64((ptr)),	\
15 	__bad_unaligned_access_size()))));					\
16 	}))
17 
18 #define __get_unaligned_be(ptr) ((__force typeof(*(ptr)))({			\
19 	__builtin_choose_expr(sizeof(*(ptr)) == 1, *(ptr),			\
20 	__builtin_choose_expr(sizeof(*(ptr)) == 2, get_unaligned_be16((ptr)),	\
21 	__builtin_choose_expr(sizeof(*(ptr)) == 4, get_unaligned_be32((ptr)),	\
22 	__builtin_choose_expr(sizeof(*(ptr)) == 8, get_unaligned_be64((ptr)),	\
23 	__bad_unaligned_access_size()))));					\
24 	}))
25 
26 #define __put_unaligned_le(val, ptr) ({					\
27 	void *__gu_p = (ptr);						\
28 	switch (sizeof(*(ptr))) {					\
29 	case 1:								\
30 		*(u8 *)__gu_p = (__force u8)(val);			\
31 		break;							\
32 	case 2:								\
33 		put_unaligned_le16((__force u16)(val), __gu_p);		\
34 		break;							\
35 	case 4:								\
36 		put_unaligned_le32((__force u32)(val), __gu_p);		\
37 		break;							\
38 	case 8:								\
39 		put_unaligned_le64((__force u64)(val), __gu_p);		\
40 		break;							\
41 	default:							\
42 		__bad_unaligned_access_size();				\
43 		break;							\
44 	}								\
45 	(void)0; })
46 
47 #define __put_unaligned_be(val, ptr) ({					\
48 	void *__gu_p = (ptr);						\
49 	switch (sizeof(*(ptr))) {					\
50 	case 1:								\
51 		*(u8 *)__gu_p = (__force u8)(val);			\
52 		break;							\
53 	case 2:								\
54 		put_unaligned_be16((__force u16)(val), __gu_p);		\
55 		break;							\
56 	case 4:								\
57 		put_unaligned_be32((__force u32)(val), __gu_p);		\
58 		break;							\
59 	case 8:								\
60 		put_unaligned_be64((__force u64)(val), __gu_p);		\
61 		break;							\
62 	default:							\
63 		__bad_unaligned_access_size();				\
64 		break;							\
65 	}								\
66 	(void)0; })
67 
68 #endif /* _LINUX_UNALIGNED_GENERIC_H */
69