xref: /minix/sys/sys/endian.h (revision 0a6a1f1d)
1 /*	$NetBSD: endian.h,v 1.29 2014/03/18 14:28:37 riastradh Exp $	*/
2 
3 /*
4  * Copyright (c) 1987, 1991, 1993
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of the University nor the names of its contributors
16  *    may be used to endorse or promote products derived from this software
17  *    without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  *
31  *	@(#)endian.h	8.1 (Berkeley) 6/11/93
32  */
33 
34 #ifndef _SYS_ENDIAN_H_
35 #define _SYS_ENDIAN_H_
36 
37 #include <sys/featuretest.h>
38 
39 /*
40  * Definitions for byte order, according to byte significance from low
41  * address to high.
42  */
43 #define	_LITTLE_ENDIAN	1234	/* LSB first: i386, vax */
44 #define	_BIG_ENDIAN	4321	/* MSB first: 68000, ibm, net */
45 #define	_PDP_ENDIAN	3412	/* LSB first in word, MSW first in long */
46 
47 
48 #if defined(_XOPEN_SOURCE) || defined(_NETBSD_SOURCE)
49 #ifndef _LOCORE
50 
51 /* C-family endian-ness definitions */
52 
53 #include <sys/ansi.h>
54 #include <sys/cdefs.h>
55 #include <sys/types.h>
56 
57 #ifndef in_addr_t
58 typedef __in_addr_t	in_addr_t;
59 #define	in_addr_t	__in_addr_t
60 #endif
61 
62 #ifndef in_port_t
63 typedef __in_port_t	in_port_t;
64 #define	in_port_t	__in_port_t
65 #endif
66 
67 __BEGIN_DECLS
68 uint32_t htonl(uint32_t) __constfunc;
69 uint16_t htons(uint16_t) __constfunc;
70 uint32_t ntohl(uint32_t) __constfunc;
71 uint16_t ntohs(uint16_t) __constfunc;
72 __END_DECLS
73 
74 #endif /* !_LOCORE */
75 #endif /* _XOPEN_SOURCE || _NETBSD_SOURCE */
76 
77 
78 #include <machine/endian_machdep.h>
79 
80 /*
81  * Define the order of 32-bit words in 64-bit words.
82  */
83 #if _BYTE_ORDER == _LITTLE_ENDIAN
84 #define _QUAD_HIGHWORD 1
85 #define _QUAD_LOWWORD 0
86 #endif
87 
88 #if _BYTE_ORDER == _BIG_ENDIAN
89 #define _QUAD_HIGHWORD 0
90 #define _QUAD_LOWWORD 1
91 #endif
92 
93 
94 #if defined(_XOPEN_SOURCE) || defined(_NETBSD_SOURCE)
95 /*
96  *  Traditional names for byteorder.  These are defined as the numeric
97  *  sequences so that third party code can "#define XXX_ENDIAN" and not
98  *  cause errors.
99  */
100 #define	LITTLE_ENDIAN	1234		/* LSB first: i386, vax */
101 #define	BIG_ENDIAN	4321		/* MSB first: 68000, ibm, net */
102 #define	PDP_ENDIAN	3412		/* LSB first in word, MSW first in long */
103 #define BYTE_ORDER	_BYTE_ORDER
104 
105 #ifndef _LOCORE
106 
107 #include <machine/bswap.h>
108 
109 /*
110  * Macros for network/external number representation conversion.
111  */
112 #if BYTE_ORDER == BIG_ENDIAN && !defined(__lint__)
113 #define	ntohl(x)	(x)
114 #define	ntohs(x)	(x)
115 #define	htonl(x)	(x)
116 #define	htons(x)	(x)
117 
118 #define	NTOHL(x)	(void) (x)
119 #define	NTOHS(x)	(void) (x)
120 #define	HTONL(x)	(void) (x)
121 #define	HTONS(x)	(void) (x)
122 
123 #else	/* LITTLE_ENDIAN || !defined(__lint__) */
124 
125 #define	ntohl(x)	bswap32(__CAST(uint32_t, (x)))
126 #define	ntohs(x)	bswap16(__CAST(uint16_t, (x)))
127 #define	htonl(x)	bswap32(__CAST(uint32_t, (x)))
128 #define	htons(x)	bswap16(__CAST(uint16_t, (x)))
129 
130 #define	NTOHL(x)	(x) = ntohl(__CAST(uint32_t, (x)))
131 #define	NTOHS(x)	(x) = ntohs(__CAST(uint16_t, (x)))
132 #define	HTONL(x)	(x) = htonl(__CAST(uint32_t, (x)))
133 #define	HTONS(x)	(x) = htons(__CAST(uint16_t, (x)))
134 #endif	/* LITTLE_ENDIAN || !defined(__lint__) */
135 
136 /*
137  * Macros to convert to a specific endianness.
138  */
139 
140 #if BYTE_ORDER == BIG_ENDIAN
141 
142 #define htobe16(x)	(x)
143 #define htobe32(x)	(x)
144 #define htobe64(x)	(x)
145 #define htole16(x)	bswap16(__CAST(uint16_t, (x)))
146 #define htole32(x)	bswap32(__CAST(uint32_t, (x)))
147 #define htole64(x)	bswap64(__CAST(uint64_t, (x)))
148 
149 #define HTOBE16(x)	__CAST(void, (x))
150 #define HTOBE32(x)	__CAST(void, (x))
151 #define HTOBE64(x)	__CAST(void, (x))
152 #define HTOLE16(x)	(x) = bswap16(__CAST(uint16_t, (x)))
153 #define HTOLE32(x)	(x) = bswap32(__CAST(uint32_t, (x)))
154 #define HTOLE64(x)	(x) = bswap64(__CAST(uint64_t, (x)))
155 
156 #else	/* LITTLE_ENDIAN */
157 
158 #define htobe16(x)	bswap16(__CAST(uint16_t, (x)))
159 #define htobe32(x)	bswap32(__CAST(uint32_t, (x)))
160 #define htobe64(x)	bswap64(__CAST(uint64_t, (x)))
161 #define htole16(x)	(x)
162 #define htole32(x)	(x)
163 #define htole64(x)	(x)
164 
165 #define HTOBE16(x)	(x) = bswap16(__CAST(uint16_t, (x)))
166 #define HTOBE32(x)	(x) = bswap32(__CAST(uint32_t, (x)))
167 #define HTOBE64(x)	(x) = bswap64(__CAST(uint64_t, (x)))
168 #define HTOLE16(x)	__CAST(void, (x))
169 #define HTOLE32(x)	__CAST(void, (x))
170 #define HTOLE64(x)	__CAST(void, (x))
171 
172 #endif	/* LITTLE_ENDIAN */
173 
174 #define be16toh(x)	htobe16(x)
175 #define be32toh(x)	htobe32(x)
176 #define be64toh(x)	htobe64(x)
177 #define le16toh(x)	htole16(x)
178 #define le32toh(x)	htole32(x)
179 #define le64toh(x)	htole64(x)
180 
181 #define BE16TOH(x)	HTOBE16(x)
182 #define BE32TOH(x)	HTOBE32(x)
183 #define BE64TOH(x)	HTOBE64(x)
184 #define LE16TOH(x)	HTOLE16(x)
185 #define LE32TOH(x)	HTOLE32(x)
186 #define LE64TOH(x)	HTOLE64(x)
187 
188 /*
189  * Routines to encode/decode big- and little-endian multi-octet values
190  * to/from an octet stream.
191  */
192 
193 #if __GNUC_PREREQ__(2, 95)
194 
195 #define __GEN_ENDIAN_ENC(bits, endian) \
196 static __inline __unused void \
197 endian ## bits ## enc(void *dst, uint ## bits ## _t u) \
198 { \
199 	u = hto ## endian ## bits (u); \
200 	__builtin_memcpy(dst, &u, sizeof(u)); \
201 }
202 
203 __GEN_ENDIAN_ENC(16, be)
204 __GEN_ENDIAN_ENC(32, be)
205 __GEN_ENDIAN_ENC(64, be)
206 __GEN_ENDIAN_ENC(16, le)
207 __GEN_ENDIAN_ENC(32, le)
208 __GEN_ENDIAN_ENC(64, le)
209 #undef __GEN_ENDIAN_ENC
210 
211 #define __GEN_ENDIAN_DEC(bits, endian) \
212 static __inline __unused uint ## bits ## _t \
213 endian ## bits ## dec(const void *buf) \
214 { \
215 	uint ## bits ## _t u; \
216 	__builtin_memcpy(&u, buf, sizeof(u)); \
217 	return endian ## bits ## toh (u); \
218 }
219 
220 __GEN_ENDIAN_DEC(16, be)
221 __GEN_ENDIAN_DEC(32, be)
222 __GEN_ENDIAN_DEC(64, be)
223 __GEN_ENDIAN_DEC(16, le)
224 __GEN_ENDIAN_DEC(32, le)
225 __GEN_ENDIAN_DEC(64, le)
226 #undef __GEN_ENDIAN_DEC
227 
228 #else	/* !(GCC >= 2.95) */
229 
230 static __inline void __unused
231 be16enc(void *buf, uint16_t u)
232 {
233 	uint8_t *p = __CAST(uint8_t *, buf);
234 
235 	p[0] = __CAST(uint8_t, ((__CAST(unsigned, u) >> 8) & 0xff));
236 	p[1] = __CAST(uint8_t, (u & 0xff));
237 }
238 
239 static __inline void __unused
240 le16enc(void *buf, uint16_t u)
241 {
242 	uint8_t *p = __CAST(uint8_t *, buf);
243 
244 	p[0] = __CAST(uint8_t, (u & 0xff));
245 	p[1] = __CAST(uint8_t, ((__CAST(unsigned, u) >> 8) & 0xff));
246 }
247 
248 static __inline uint16_t __unused
249 be16dec(const void *buf)
250 {
251 	const uint8_t *p = __CAST(const uint8_t *, buf);
252 
253 	return ((__CAST(uint16_t, p[0]) << 8) | p[1]);
254 }
255 
256 static __inline uint16_t __unused
257 le16dec(const void *buf)
258 {
259 	const uint8_t *p = __CAST(const uint8_t *, buf);
260 
261 	return (p[0] | (__CAST(uint16_t, p[1]) << 8));
262 }
263 
264 static __inline void __unused
265 be32enc(void *buf, uint32_t u)
266 {
267 	uint8_t *p = __CAST(uint8_t *, buf);
268 
269 	p[0] = __CAST(uint8_t, ((u >> 24) & 0xff));
270 	p[1] = __CAST(uint8_t, ((u >> 16) & 0xff));
271 	p[2] = __CAST(uint8_t, ((u >> 8) & 0xff));
272 	p[3] = __CAST(uint8_t, (u & 0xff));
273 }
274 
275 static __inline void __unused
276 le32enc(void *buf, uint32_t u)
277 {
278 	uint8_t *p = __CAST(uint8_t *, buf);
279 
280 	p[0] = __CAST(uint8_t, (u & 0xff));
281 	p[1] = __CAST(uint8_t, ((u >> 8) & 0xff));
282 	p[2] = __CAST(uint8_t, ((u >> 16) & 0xff));
283 	p[3] = __CAST(uint8_t, ((u >> 24) & 0xff));
284 }
285 
286 static __inline uint32_t __unused
287 be32dec(const void *buf)
288 {
289 	const uint8_t *p = __CAST(const uint8_t *, buf);
290 
291 	return ((__CAST(uint32_t, be16dec(p)) << 16) | be16dec(p + 2));
292 }
293 
294 static __inline uint32_t __unused
295 le32dec(const void *buf)
296 {
297 	const uint8_t *p = __CAST(const uint8_t *, buf);
298 
299 	return (le16dec(p) | (__CAST(uint32_t, le16dec(p + 2)) << 16));
300 }
301 
302 static __inline void __unused
303 be64enc(void *buf, uint64_t u)
304 {
305 	uint8_t *p = __CAST(uint8_t *, buf);
306 
307 	be32enc(p, __CAST(uint32_t, (u >> 32)));
308 	be32enc(p + 4, __CAST(uint32_t, (u & 0xffffffffULL)));
309 }
310 
311 static __inline void __unused
312 le64enc(void *buf, uint64_t u)
313 {
314 	uint8_t *p = __CAST(uint8_t *, buf);
315 
316 	le32enc(p, __CAST(uint32_t, (u & 0xffffffffULL)));
317 	le32enc(p + 4, __CAST(uint32_t, (u >> 32)));
318 }
319 
320 static __inline uint64_t __unused
321 be64dec(const void *buf)
322 {
323 	const uint8_t *p = (const uint8_t *)buf;
324 
325 	return ((__CAST(uint64_t, be32dec(p)) << 32) | be32dec(p + 4));
326 }
327 
328 static __inline uint64_t __unused
329 le64dec(const void *buf)
330 {
331 	const uint8_t *p = (const uint8_t *)buf;
332 
333 	return (le32dec(p) | (__CAST(uint64_t, le32dec(p + 4)) << 32));
334 }
335 
336 #endif	/* GCC >= 2.95 */
337 
338 #endif /* !_LOCORE */
339 #endif /* _XOPEN_SOURCE || _NETBSD_SOURCE */
340 #endif /* !_SYS_ENDIAN_H_ */
341