allow coexistance of N build and AC build.
[tomato.git] / release / src-rt-6.x / linux / linux-2.6 / include / asm-generic / unaligned.h
blob77d5c9681f5306af433291f8d12585755ad71eab
1 #ifndef _ASM_GENERIC_UNALIGNED_H_
2 #define _ASM_GENERIC_UNALIGNED_H_
4 /*
5 * For the benefit of those who are trying to port Linux to another
6 * architecture, here are some C-language equivalents.
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.
13 #include <linux/types.h>
15 struct __una_u64 { __u64 x; } __attribute__((packed));
16 struct __una_u32 { __u32 x; } __attribute__((packed));
17 struct __una_u16 { __u16 x; } __attribute__((packed));
20 * Elemental unaligned loads
23 static inline __u64 __get_unaligned_cpu64(const void *addr)
25 const struct __una_u64 *ptr = (const struct __una_u64 *) addr;
26 return ptr->x;
29 static inline __u32 __get_unaligned_cpu32(const void *addr)
31 const struct __una_u32 *ptr = (const struct __una_u32 *) addr;
32 return ptr->x;
35 static inline __u16 __get_unaligned_cpu16(const void *addr)
37 const struct __una_u16 *ptr = (const struct __una_u16 *) addr;
38 return ptr->x;
42 * Elemental unaligned stores
45 static inline void __put_unaligned_cpu64(__u64 val, void *addr)
47 struct __una_u64 *ptr = (struct __una_u64 *) addr;
48 ptr->x = val;
51 static inline void __put_unaligned_cpu32(__u32 val, void *addr)
53 struct __una_u32 *ptr = (struct __una_u32 *) addr;
54 ptr->x = val;
57 static inline void __put_unaligned_cpu16(__u16 val, void *addr)
59 struct __una_u16 *ptr = (struct __una_u16 *) addr;
60 ptr->x = val;
63 #include <asm/byteorder.h>
65 #if defined(__LITTLE_ENDIAN)
66 # include <linux/unaligned/le_struct.h>
67 # include <linux/unaligned/be_byteshift.h>
68 # define get_unaligned __get_unaligned_le
69 # define put_unaligned __put_unaligned_le
70 #elif defined(__BIG_ENDIAN)
71 # include <linux/unaligned/be_struct.h>
72 # include <linux/unaligned/le_byteshift.h>
73 # define get_unaligned __get_unaligned_be
74 # define put_unaligned __put_unaligned_be
75 #else
76 # error need to define endianess
77 #endif
80 * Cause a link-time error if we try an unaligned access other than
81 * 1,2,4 or 8 bytes long
83 extern void __bad_unaligned_access_size(void);
85 #define __get_unaligned_le(ptr) ((__force typeof(*(ptr)))({ \
86 __builtin_choose_expr(sizeof(*(ptr)) == 1, *(ptr), \
87 __builtin_choose_expr(sizeof(*(ptr)) == 2, get_unaligned_le16((ptr)), \
88 __builtin_choose_expr(sizeof(*(ptr)) == 4, get_unaligned_le32((ptr)), \
89 __builtin_choose_expr(sizeof(*(ptr)) == 8, get_unaligned_le64((ptr)), \
90 __bad_unaligned_access_size())))); \
91 }))
93 #define __get_unaligned_be(ptr) ((__force typeof(*(ptr)))({ \
94 __builtin_choose_expr(sizeof(*(ptr)) == 1, *(ptr), \
95 __builtin_choose_expr(sizeof(*(ptr)) == 2, get_unaligned_be16((ptr)), \
96 __builtin_choose_expr(sizeof(*(ptr)) == 4, get_unaligned_be32((ptr)), \
97 __builtin_choose_expr(sizeof(*(ptr)) == 8, get_unaligned_be64((ptr)), \
98 __bad_unaligned_access_size())))); \
99 }))
101 #define __put_unaligned_le(val, ptr) ({ \
102 void *__gu_p = (ptr); \
103 switch (sizeof(*(ptr))) { \
104 case 1: \
105 *(u8 *)__gu_p = (__force u8)(val); \
106 break; \
107 case 2: \
108 put_unaligned_le16((__force u16)(val), __gu_p); \
109 break; \
110 case 4: \
111 put_unaligned_le32((__force u32)(val), __gu_p); \
112 break; \
113 case 8: \
114 put_unaligned_le64((__force u64)(val), __gu_p); \
115 break; \
116 default: \
117 __bad_unaligned_access_size(); \
118 break; \
120 (void)0; })
122 #define __put_unaligned_be(val, ptr) ({ \
123 void *__gu_p = (ptr); \
124 switch (sizeof(*(ptr))) { \
125 case 1: \
126 *(u8 *)__gu_p = (__force u8)(val); \
127 break; \
128 case 2: \
129 put_unaligned_be16((__force u16)(val), __gu_p); \
130 break; \
131 case 4: \
132 put_unaligned_be32((__force u32)(val), __gu_p); \
133 break; \
134 case 8: \
135 put_unaligned_be64((__force u64)(val), __gu_p); \
136 break; \
137 default: \
138 __bad_unaligned_access_size(); \
139 break; \
141 (void)0; })
143 #endif /* _ASM_GENERIC_UNALIGNED_H */