xref: /freebsd/sys/contrib/openzfs/lib/libspl/include/os/linux/sys/byteorder.h (revision 61145dc2b94f12f6a47344fb9aac702321880e43)
1 // SPDX-License-Identifier: CDDL-1.0
2 /*
3  * CDDL HEADER START
4  *
5  * The contents of this file are subject to the terms of the
6  * Common Development and Distribution License (the "License").
7  * You may not use this file except in compliance with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or https://opensource.org/licenses/CDDL-1.0.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 
23 /*
24  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
25  * Use is subject to license terms.
26  */
27 
28 /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
29 /*	  All Rights Reserved  	*/
30 
31 /*
32  * University Copyright- Copyright (c) 1982, 1986, 1988
33  * The Regents of the University of California
34  * All Rights Reserved
35  *
36  * University Acknowledgment- Portions of this document are derived from
37  * software developed by the University of California, Berkeley, and its
38  * contributors.
39  */
40 
41 #ifndef _SYS_BYTEORDER_H
42 #define	_SYS_BYTEORDER_H
43 
44 #if defined(__GNUC__) && defined(_ASM_INLINES) && \
45 	(defined(__i386) || defined(__amd64))
46 #include <asm/byteorder.h>
47 #endif
48 
49 #include <sys/isa_defs.h>
50 #include <inttypes.h>
51 
52 #ifdef	__cplusplus
53 extern "C" {
54 #endif
55 
56 /*
57  * macros for conversion between host and (internet) network byte order
58  */
59 
60 #if defined(_ZFS_BIG_ENDIAN) && !defined(ntohl) && !defined(__lint)
61 /* big-endian */
62 #define	ntohl(x)	(x)
63 #define	ntohs(x)	(x)
64 #define	htonl(x)	(x)
65 #define	htons(x)	(x)
66 
67 #elif !defined(ntohl) /* little-endian */
68 
69 #ifndef	_IN_PORT_T
70 #define	_IN_PORT_T
71 typedef uint16_t in_port_t;
72 #endif
73 
74 #ifndef	_IN_ADDR_T
75 #define	_IN_ADDR_T
76 typedef uint32_t in_addr_t;
77 #endif
78 
79 #if !defined(_XPG4_2) || defined(__EXTENSIONS__) || defined(_XPG5)
80 extern	uint32_t htonl(uint32_t);
81 extern	uint16_t htons(uint16_t);
82 extern 	uint32_t ntohl(uint32_t);
83 extern	uint16_t ntohs(uint16_t);
84 #else
85 extern	in_addr_t htonl(in_addr_t);
86 extern	in_port_t htons(in_port_t);
87 extern 	in_addr_t ntohl(in_addr_t);
88 extern	in_port_t ntohs(in_port_t);
89 #endif	/* !defined(_XPG4_2) || defined(__EXTENSIONS__) || defined(_XPG5) */
90 #endif
91 
92 #if !defined(_XPG4_2) || defined(__EXTENSIONS__)
93 
94 #ifdef __COVERITY__
95 /*
96  * Coverity's taint warnings from byteswapping are false positives for us.
97  * Suppress them by hiding byteswapping from Coverity.
98  */
99 #define	BSWAP_8(x)	((x) & 0xff)
100 #define	BSWAP_16(x)	((x) & 0xffff)
101 #define	BSWAP_32(x)	((x) & 0xffffffff)
102 #define	BSWAP_64(x)	(x)
103 
104 #else /* __COVERITY__ */
105 
106 /*
107  * Macros to reverse byte order
108  */
109 #define	BSWAP_8(x)	((x) & 0xff)
110 #define	BSWAP_16(x)	((BSWAP_8(x) << 8) | BSWAP_8((x) >> 8))
111 #define	BSWAP_32(x)	((BSWAP_16(x) << 16) | BSWAP_16((x) >> 16))
112 #define	BSWAP_64(x)	((BSWAP_32(x) << 32) | BSWAP_32((x) >> 32))
113 
114 #endif /* __COVERITY__ */
115 
116 #define	BMASK_8(x)	((x) & 0xff)
117 #define	BMASK_16(x)	((x) & 0xffff)
118 #define	BMASK_32(x)	((x) & 0xffffffff)
119 #define	BMASK_64(x)	(x)
120 
121 /*
122  * Macros to convert from a specific byte order to/from native byte order
123  */
124 #ifdef _ZFS_BIG_ENDIAN
125 #define	BE_8(x)		BMASK_8(x)
126 #define	BE_16(x)	BMASK_16(x)
127 #define	BE_32(x)	BMASK_32(x)
128 #define	BE_64(x)	BMASK_64(x)
129 #define	LE_8(x)		BSWAP_8(x)
130 #define	LE_16(x)	BSWAP_16(x)
131 #define	LE_32(x)	BSWAP_32(x)
132 #define	LE_64(x)	BSWAP_64(x)
133 #else
134 #define	LE_8(x)		BMASK_8(x)
135 #define	LE_16(x)	BMASK_16(x)
136 #define	LE_32(x)	BMASK_32(x)
137 #define	LE_64(x)	BMASK_64(x)
138 #define	BE_8(x)		BSWAP_8(x)
139 #define	BE_16(x)	BSWAP_16(x)
140 #define	BE_32(x)	BSWAP_32(x)
141 #define	BE_64(x)	BSWAP_64(x)
142 #endif
143 
144 #ifdef _ZFS_BIG_ENDIAN
145 static __inline__ uint64_t
htonll(uint64_t n)146 htonll(uint64_t n)
147 {
148 	return (n);
149 }
150 
151 static __inline__ uint64_t
ntohll(uint64_t n)152 ntohll(uint64_t n)
153 {
154 	return (n);
155 }
156 #else
157 static __inline__ uint64_t
158 htonll(uint64_t n)
159 {
160 	return ((((uint64_t)htonl(n)) << 32) + htonl(n >> 32));
161 }
162 
163 static __inline__ uint64_t
164 ntohll(uint64_t n)
165 {
166 	return ((((uint64_t)ntohl(n)) << 32) + ntohl(n >> 32));
167 }
168 #endif
169 
170 /*
171  * Macros to read unaligned values from a specific byte order to
172  * native byte order
173  */
174 
175 #define	BE_IN8(xa) \
176 	*((uint8_t *)(xa))
177 
178 #define	BE_IN16(xa) \
179 	(((uint16_t)BE_IN8(xa) << 8) | BE_IN8((uint8_t *)(xa)+1))
180 
181 #define	BE_IN32(xa) \
182 	(((uint32_t)BE_IN16(xa) << 16) | BE_IN16((uint8_t *)(xa)+2))
183 
184 #define	BE_IN64(xa) \
185 	(((uint64_t)BE_IN32(xa) << 32) | BE_IN32((uint8_t *)(xa)+4))
186 
187 #define	LE_IN8(xa) \
188 	*((uint8_t *)(xa))
189 
190 #define	LE_IN16(xa) \
191 	(((uint16_t)LE_IN8((uint8_t *)(xa) + 1) << 8) | LE_IN8(xa))
192 
193 #define	LE_IN32(xa) \
194 	(((uint32_t)LE_IN16((uint8_t *)(xa) + 2) << 16) | LE_IN16(xa))
195 
196 #define	LE_IN64(xa) \
197 	(((uint64_t)LE_IN32((uint8_t *)(xa) + 4) << 32) | LE_IN32(xa))
198 
199 /*
200  * Macros to write unaligned values from native byte order to a specific byte
201  * order.
202  */
203 
204 #define	BE_OUT8(xa, yv) *((uint8_t *)(xa)) = (uint8_t)(yv);
205 
206 #define	BE_OUT16(xa, yv) \
207 	BE_OUT8((uint8_t *)(xa) + 1, yv); \
208 	BE_OUT8((uint8_t *)(xa), (yv) >> 8);
209 
210 #define	BE_OUT32(xa, yv) \
211 	BE_OUT16((uint8_t *)(xa) + 2, yv); \
212 	BE_OUT16((uint8_t *)(xa), (yv) >> 16);
213 
214 #define	BE_OUT64(xa, yv) \
215 	BE_OUT32((uint8_t *)(xa) + 4, yv); \
216 	BE_OUT32((uint8_t *)(xa), (yv) >> 32);
217 
218 #define	LE_OUT8(xa, yv) *((uint8_t *)(xa)) = (uint8_t)(yv);
219 
220 #define	LE_OUT16(xa, yv) \
221 	LE_OUT8((uint8_t *)(xa), yv); \
222 	LE_OUT8((uint8_t *)(xa) + 1, (yv) >> 8);
223 
224 #define	LE_OUT32(xa, yv) \
225 	LE_OUT16((uint8_t *)(xa), yv); \
226 	LE_OUT16((uint8_t *)(xa) + 2, (yv) >> 16);
227 
228 #define	LE_OUT64(xa, yv) \
229 	LE_OUT32((uint8_t *)(xa), yv); \
230 	LE_OUT32((uint8_t *)(xa) + 4, (yv) >> 32);
231 
232 #endif	/* !defined(_XPG4_2) || defined(__EXTENSIONS__) */
233 
234 #ifdef	__cplusplus
235 }
236 #endif
237 
238 #endif /* _SYS_BYTEORDER_H */
239