1 /*-
2 * Copyright (c) 2002 Thomas Moestl <tmm@FreeBSD.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $FreeBSD: releng/10.1/sys/sys/endian.h 208331 2010-05-20 06:16:13Z phk $
27 */
28
29 #ifndef _SYS_ENDIAN_H_
30 #define _SYS_ENDIAN_H_
31
32 #include <rtthread.h>
33 #include "sunxi_hal_common.h"
34
35 #ifdef CONFIG_RTTKERNEL
36
37 #ifndef _LITTLE_ENDIAN
38 #define _LITTLE_ENDIAN 1
39 #endif
40
41 #define _BYTE_ORDER _LITTLE_ENDIAN
42
43 #ifndef __bswap32
44
45 #if ((defined(__GNUC__) && !defined(__CC_ARM)))
46
47 #define __bswap16(x) ((uint16_t)__builtin_bswap16(x))
48 #define __bswap32(x) ((uint32_t)__builtin_bswap32(x))
49 #define __bswap64(x) ((uint64_t)__builtin_bswap64(x))
50
51 #else /* ((defined(__GNUC__) && !defined(__CC_ARM))) */
52
53 #define __bswap16(x) ((uint16_t)( \
54 (((uint16_t)(x) & (uint16_t)0x00ffU) << 8) | \
55 (((uint16_t)(x) & (uint16_t)0xff00U) >> 8)))
56
57 #define __bswap32(x) ((uint32_t)( \
58 (((uint32_t)(x) & (uint32_t)0x000000ffUL) << 24) | \
59 (((uint32_t)(x) & (uint32_t)0x0000ff00UL) << 8) | \
60 (((uint32_t)(x) & (uint32_t)0x00ff0000UL) >> 8) | \
61 (((uint32_t)(x) & (uint32_t)0xff000000UL) >> 24)))
62
63 #define __bswap64(x) ((uint64_t)( \
64 (((uint64_t)(x) & (uint64_t)0x00000000000000ffULL) << 56) | \
65 (((uint64_t)(x) & (uint64_t)0x000000000000ff00ULL) << 40) | \
66 (((uint64_t)(x) & (uint64_t)0x0000000000ff0000ULL) << 24) | \
67 (((uint64_t)(x) & (uint64_t)0x00000000ff000000ULL) << 8) | \
68 (((uint64_t)(x) & (uint64_t)0x000000ff00000000ULL) >> 8) | \
69 (((uint64_t)(x) & (uint64_t)0x0000ff0000000000ULL) >> 24) | \
70 (((uint64_t)(x) & (uint64_t)0x00ff000000000000ULL) >> 40) | \
71 (((uint64_t)(x) & (uint64_t)0xff00000000000000ULL) >> 56)))
72
73 #endif /* ((defined(__GNUC__) && !defined(__CC_ARM))) */
74
75 #else /* __bswap32 */
76
77 #undef __bswap32
78 #define __bswap32(x) (uint32_t)__builtin_bswap32(x)
79
80 #endif /* __bswap32 */
81
82 /*
83 * General byte order swapping functions.
84 */
85 #define bswap16(x) __bswap16(x)
86 #define bswap32(x) __bswap32(x)
87 #define bswap64(x) __bswap64(x)
88
89 /*
90 * Host to big endian, host to little endian, big endian to host, and little
91 * endian to host byte order functions as detailed in byteorder(9).
92 */
93 #if _BYTE_ORDER == _LITTLE_ENDIAN
94 #define htobe16(x) bswap16((x))
95 #define htobe32(x) bswap32((x))
96 #define htobe64(x) bswap64((x))
97 #define htole16(x) ((uint16_t)(x))
98 #define htole32(x) ((uint32_t)(x))
99 #define htole64(x) ((uint64_t)(x))
100
101 #define be16toh(x) bswap16((x))
102 #define be32toh(x) bswap32((x))
103 #define be64toh(x) bswap64((x))
104 #define le16toh(x) ((uint16_t)(x))
105 #define le32toh(x) ((uint32_t)(x))
106 #define le64toh(x) ((uint64_t)(x))
107 #elif (_BYTE_ORDER == _BIG_ENDIAN)
108 #define htobe16(x) ((uint16_t)(x))
109 #define htobe32(x) ((uint32_t)(x))
110 #define htobe64(x) ((uint64_t)(x))
111 #define htole16(x) bswap16((x))
112 #define htole32(x) bswap32((x))
113 #define htole64(x) bswap64((x))
114
115 #define be16toh(x) ((uint16_t)(x))
116 #define be32toh(x) ((uint32_t)(x))
117 #define be64toh(x) ((uint64_t)(x))
118 #define le16toh(x) bswap16((x))
119 #define le32toh(x) bswap32((x))
120 #define le64toh(x) bswap64((x))
121 #else
122 #error "Endian not defined!"
123 #endif /* _BYTE_ORDER == _LITTLE_ENDIAN */
124 #endif
125
126 #define __cpu_to_le64(x) htole64(x)
127 #define __le64_to_cpu(x) le64toh(x)
128 #define __cpu_to_le32(x) htole32(x)
129 #define __le32_to_cpu(x) le32toh(x)
130 #define __cpu_to_le16(x) htole16(x)
131 #define __le16_to_cpu(x) le16toh(x)
132 #define __cpu_to_be64(x) htobe64(x)
133 #define __be64_to_cpu(x) be64toh(x)
134 #define __cpu_to_be32(x) htobe32(x)
135 #define __be32_to_cpu(x) be32toh(x)
136 #define __cpu_to_be16(x) htobe16(x)
137 #define __be16_to_cpu(x) be16toh(x)
138
139 #define cpu_to_le64 __cpu_to_le64
140 #define le64_to_cpu __le64_to_cpu
141 #define cpu_to_le32 __cpu_to_le32
142 #define le32_to_cpu __le32_to_cpu
143 #define cpu_to_le16 __cpu_to_le16
144 #define le16_to_cpu __le16_to_cpu
145 #define cpu_to_be64 __cpu_to_be64
146 #define be64_to_cpu __be64_to_cpu
147 #define cpu_to_be32 __cpu_to_be32
148 #define be32_to_cpu __be32_to_cpu
149 #define cpu_to_be16 __cpu_to_be16
150 #define be16_to_cpu __be16_to_cpu
151
152
153 /* Alignment-agnostic encode/decode bytestream to/from little/big endian. */
154
155 static __inline uint16_t
be16dec(const void * pp)156 be16dec(const void *pp)
157 {
158 uint8_t const *p = (uint8_t const *)pp;
159
160 return ((p[0] << 8) | p[1]);
161 }
162
163 static __inline uint32_t
be32dec(const void * pp)164 be32dec(const void *pp)
165 {
166 uint8_t const *p = (uint8_t const *)pp;
167
168 return (((unsigned)p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]);
169 }
170
171 static __inline uint64_t
be64dec(const void * pp)172 be64dec(const void *pp)
173 {
174 uint8_t const *p = (uint8_t const *)pp;
175
176 return (((uint64_t)be32dec(p) << 32) | be32dec(p + 4));
177 }
178
179 static __inline uint16_t
le16dec(const void * pp)180 le16dec(const void *pp)
181 {
182 uint8_t const *p = (uint8_t const *)pp;
183
184 return ((p[1] << 8) | p[0]);
185 }
186
187 static __inline uint32_t
le32dec(const void * pp)188 le32dec(const void *pp)
189 {
190 uint8_t const *p = (uint8_t const *)pp;
191
192 return (((unsigned)p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]);
193 }
194
195 static __inline uint64_t
le64dec(const void * pp)196 le64dec(const void *pp)
197 {
198 uint8_t const *p = (uint8_t const *)pp;
199
200 return (((uint64_t)le32dec(p + 4) << 32) | le32dec(p));
201 }
202
203 static __inline void
be16enc(void * pp,uint16_t u)204 be16enc(void *pp, uint16_t u)
205 {
206 uint8_t *p = (uint8_t *)pp;
207
208 p[0] = (u >> 8) & 0xff;
209 p[1] = u & 0xff;
210 }
211
212 static __inline void
be32enc(void * pp,uint32_t u)213 be32enc(void *pp, uint32_t u)
214 {
215 uint8_t *p = (uint8_t *)pp;
216
217 p[0] = (u >> 24) & 0xff;
218 p[1] = (u >> 16) & 0xff;
219 p[2] = (u >> 8) & 0xff;
220 p[3] = u & 0xff;
221 }
222
223 static __inline void
be64enc(void * pp,uint64_t u)224 be64enc(void *pp, uint64_t u)
225 {
226 uint8_t *p = (uint8_t *)pp;
227
228 be32enc(p, (uint32_t)(u >> 32));
229 be32enc(p + 4, (uint32_t)(u & 0xffffffffU));
230 }
231
232 static __inline void
le16enc(void * pp,uint16_t u)233 le16enc(void *pp, uint16_t u)
234 {
235 uint8_t *p = (uint8_t *)pp;
236
237 p[0] = u & 0xff;
238 p[1] = (u >> 8) & 0xff;
239 }
240
241 static __inline void
le32enc(void * pp,uint32_t u)242 le32enc(void *pp, uint32_t u)
243 {
244 uint8_t *p = (uint8_t *)pp;
245
246 p[0] = u & 0xff;
247 p[1] = (u >> 8) & 0xff;
248 p[2] = (u >> 16) & 0xff;
249 p[3] = (u >> 24) & 0xff;
250 }
251
252 static __inline void
le64enc(void * pp,uint64_t u)253 le64enc(void *pp, uint64_t u)
254 {
255 uint8_t *p = (uint8_t *)pp;
256
257 le32enc(p, (uint32_t)(u & 0xffffffffU));
258 le32enc(p + 4, (uint32_t)(u >> 32));
259 }
260
261 #endif /* _SYS_ENDIAN_H_ */
262