2 * UCW Library -- Fast Access to Unaligned Data
4 * (c) 1997--2007 Martin Mares <mj@ucw.cz>
6 * This software may be freely distributed and used according to the terms
7 * of the GNU Lesser General Public License.
10 #ifndef _UCW_UNALIGNED_H
11 #define _UCW_UNALIGNED_H
13 /* Big endian format */
15 #if defined(CPU_ALLOW_UNALIGNED) && defined(CPU_BIG_ENDIAN)
16 static inline uns get_u16_be(const void *p) { return *(u16 *)p; }
17 static inline u32 get_u32_be(const void *p) { return *(u32 *)p; }
18 static inline u64 get_u64_be(const void *p) { return *(u64 *)p; }
19 static inline void put_u16_be(void *p, uns x) { *(u16 *)p = x; }
20 static inline void put_u32_be(void *p, u32 x) { *(u32 *)p = x; }
21 static inline void put_u64_be(void *p, u64 x) { *(u64 *)p = x; }
23 static inline uns get_u16_be(const void *p)
26 return (c[0] << 8) | c[1];
28 static inline u32 get_u32_be(const void *p)
31 return (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3];
33 static inline u64 get_u64_be(const void *p)
35 return ((u64) get_u32_be(p) << 32) | get_u32_be((const byte *)p+4);
37 static inline void put_u16_be(void *p, uns x)
43 static inline void put_u32_be(void *p, u32 x)
51 static inline void put_u64_be(void *p, u64 x)
53 put_u32_be(p, x >> 32);
54 put_u32_be((byte *)p+4, x);
58 /* Little-endian format */
60 #if defined(CPU_ALLOW_UNALIGNED) && !defined(CPU_BIG_ENDIAN)
61 static inline uns get_u16_le(const void *p) { return *(u16 *)p; }
62 static inline u32 get_u32_le(const void *p) { return *(u32 *)p; }
63 static inline u64 get_u64_le(const void *p) { return *(u64 *)p; }
64 static inline void put_u16_le(void *p, uns x) { *(u16 *)p = x; }
65 static inline void put_u32_le(void *p, u32 x) { *(u32 *)p = x; }
66 static inline void put_u64_le(void *p, u64 x) { *(u64 *)p = x; }
68 static inline uns get_u16_le(const void *p)
71 return c[0] | (c[1] << 8);
73 static inline u32 get_u32_le(const void *p)
76 return c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24);
78 static inline u64 get_u64_le(const void *p)
80 return get_u32_le(p) | ((u64) get_u32_le((const byte *)p+4) << 32);
82 static inline void put_u16_le(void *p, uns x)
88 static inline void put_u32_le(void *p, u32 x)
96 static inline void put_u64_le(void *p, u64 x)
99 put_u32_le((byte *)p+4, x >> 32);
103 static inline u64 get_u40_be(const void *p)
106 return ((u64)c[0] << 32) | get_u32_be(c+1);
109 static inline void put_u40_be(void *p, u64 x)
116 static inline u64 get_u40_le(const void *p)
119 return get_u32_le(c) | ((u64) c[4] << 32);
122 static inline void put_u40_le(void *p, u64 x)
129 /* The native format */
131 #ifdef CPU_BIG_ENDIAN
133 static inline uns get_u16(const void *p) { return get_u16_be(p); }
134 static inline u32 get_u32(const void *p) { return get_u32_be(p); }
135 static inline u64 get_u64(const void *p) { return get_u64_be(p); }
136 static inline u64 get_u40(const void *p) { return get_u40_be(p); }
137 static inline void put_u16(void *p, uns x) { return put_u16_be(p, x); }
138 static inline void put_u32(void *p, u32 x) { return put_u32_be(p, x); }
139 static inline void put_u64(void *p, u64 x) { return put_u64_be(p, x); }
140 static inline void put_u40(void *p, u64 x) { return put_u40_be(p, x); }
144 static inline uns get_u16(const void *p) { return get_u16_le(p); }
145 static inline u32 get_u32(const void *p) { return get_u32_le(p); }
146 static inline u64 get_u64(const void *p) { return get_u64_le(p); }
147 static inline u64 get_u40(const void *p) { return get_u40_le(p); }
148 static inline void put_u16(void *p, uns x) { return put_u16_le(p, x); }
149 static inline void put_u32(void *p, u32 x) { return put_u32_le(p, x); }
150 static inline void put_u64(void *p, u64 x) { return put_u64_le(p, x); }
151 static inline void put_u40(void *p, u64 x) { return put_u40_le(p, x); }
155 /* Just for completeness */
157 static inline uns get_u8(const void *p) { return *(const byte *)p; }
158 static inline void put_u8(void *p, uns x) { *(byte *)p = x; }
160 /* Backward compatibility macros */
162 #define GET_U8(p) get_u8(p)
163 #define GET_U16(p) get_u16(p)
164 #define GET_U32(p) get_u32(p)
165 #define GET_U64(p) get_u64(p)
166 #define GET_U40(p) get_u40(p)
168 #define PUT_U8(p,x) put_u8(p,x);
169 #define PUT_U16(p,x) put_u16(p,x)
170 #define PUT_U32(p,x) put_u32(p,x)
171 #define PUT_U64(p,x) put_u64(p,x)
172 #define PUT_U40(p,x) put_u40(p,x)