xref: /NextBSD/include/libkern/OSByteOrder.h (revision ae7281ba342a6109cceb2484d8bcc13b0a24b293)
1 /*
2  * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved.
3  *
4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5  *
6  * This file contains Original Code and/or Modifications of Original Code
7  * as defined in and that are subject to the Apple Public Source License
8  * Version 2.0 (the 'License'). You may not use this file except in
9  * compliance with the License. The rights granted to you under the License
10  * may not be used to create, or enable the creation or redistribution of,
11  * unlawful or unlicensed copies of an Apple operating system, or to
12  * circumvent, violate, or enable the circumvention or violation of, any
13  * terms of an Apple operating system software license agreement.
14  *
15  * Please obtain a copy of the License at
16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17  *
18  * The Original Code and all software distributed under the License are
19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23  * Please see the License for the specific language governing rights and
24  * limitations under the License.
25  *
26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27  */
28 
29 #ifndef _OS_OSBYTEORDER_H
30 #define _OS_OSBYTEORDER_H
31 
32 #include <stdint.h>
33 #include <libkern/_OSByteOrder.h>
34 
35 /* Macros for swapping constant values in the preprocessing stage. */
36 #define OSSwapConstInt16(x)	__DARWIN_OSSwapConstInt16(x)
37 #define OSSwapConstInt32(x)	__DARWIN_OSSwapConstInt32(x)
38 #define OSSwapConstInt64(x)	__DARWIN_OSSwapConstInt64(x)
39 
40 
41 #include <sys/endian.h>
42 #ifndef OS_INLINE
43 #define OS_INLINE static inline
44 #endif
45 
46 OS_INLINE
47 uint16_t
OSReadSwapInt16(const volatile void * base,uintptr_t byteOffset)48 OSReadSwapInt16(
49     const volatile void   * base,
50     uintptr_t       byteOffset
51 )
52 {
53     uint16_t result;
54 
55     result = *(volatile uint16_t *)((uintptr_t)base + byteOffset);
56     return bswap16(result);
57 }
58 
59 OS_INLINE
60 uint32_t
OSReadSwapInt32(const volatile void * base,uintptr_t byteOffset)61 OSReadSwapInt32(
62     const volatile void   * base,
63     uintptr_t       byteOffset
64 )
65 {
66     uint32_t result;
67 
68     result = *(volatile uint32_t *)((uintptr_t)base + byteOffset);
69     return bswap32(result);
70 }
71 
72 OS_INLINE
73 uint64_t
OSReadSwapInt64(const volatile void * base,uintptr_t byteOffset)74 OSReadSwapInt64(
75     const volatile void   * base,
76     uintptr_t       byteOffset
77 )
78 {
79     uint64_t result;
80 
81     result = *(volatile uint64_t *)((uintptr_t)base + byteOffset);
82     return bswap64(result);
83 }
84 
85 /* Functions for byte reversed stores. */
86 
87 OS_INLINE
88 void
OSWriteSwapInt16(volatile void * base,uintptr_t byteOffset,uint16_t data)89 OSWriteSwapInt16(
90     volatile void   * base,
91     uintptr_t       byteOffset,
92     uint16_t        data
93 )
94 {
95     *(volatile uint16_t *)((uintptr_t)base + byteOffset) = bswap16(data);
96 }
97 
98 OS_INLINE
99 void
OSWriteSwapInt32(volatile void * base,uintptr_t byteOffset,uint32_t data)100 OSWriteSwapInt32(
101     volatile void   * base,
102     uintptr_t       byteOffset,
103     uint32_t        data
104 )
105 {
106     *(volatile uint32_t *)((uintptr_t)base + byteOffset) = bswap32(data);
107 }
108 
109 OS_INLINE
110 void
OSWriteSwapInt64(volatile void * base,uintptr_t byteOffset,uint64_t data)111 OSWriteSwapInt64(
112     volatile void    * base,
113     uintptr_t        byteOffset,
114     uint64_t         data
115 )
116 {
117     *(volatile uint64_t *)((uintptr_t)base + byteOffset) = bswap64(data);
118 }
119 
120 
121 #define OSSwapInt16(x)	__DARWIN_OSSwapInt16(x)
122 #define OSSwapInt32(x)	__DARWIN_OSSwapInt32(x)
123 #define OSSwapInt64(x)	__DARWIN_OSSwapInt64(x)
124 
125 enum {
126     OSUnknownByteOrder,
127     OSLittleEndian,
128     OSBigEndian
129 };
130 
131 OS_INLINE
132 int32_t
OSHostByteOrder(void)133 OSHostByteOrder(void) {
134 #if defined(__LITTLE_ENDIAN__)
135     return OSLittleEndian;
136 #elif defined(__BIG_ENDIAN__)
137     return OSBigEndian;
138 #else
139     return OSUnknownByteOrder;
140 #endif
141 }
142 
143 #define OSReadBigInt(x, y)		OSReadBigInt32(x, y)
144 #define OSWriteBigInt(x, y, z)		OSWriteBigInt32(x, y, z)
145 #define OSSwapBigToHostInt(x)		OSSwapBigToHostInt32(x)
146 #define OSSwapHostToBigInt(x)		OSSwapHostToBigInt32(x)
147 #define OSReadLittleInt(x, y)		OSReadLittleInt32(x, y)
148 #define OSWriteLittleInt(x, y, z)	OSWriteLittleInt32(x, y, z)
149 #define OSSwapHostToLittleInt(x)	OSSwapHostToLittleInt32(x)
150 #define OSSwapLittleToHostInt(x)	OSSwapLittleToHostInt32(x)
151 
152 /* Functions for loading native endian values. */
153 
154 OS_INLINE
155 uint16_t
_OSReadInt16(const volatile void * base,uintptr_t byteOffset)156 _OSReadInt16(
157     const volatile void               * base,
158     uintptr_t                     byteOffset
159 )
160 {
161     return *(volatile uint16_t *)((uintptr_t)base + byteOffset);
162 }
163 
164 OS_INLINE
165 uint32_t
_OSReadInt32(const volatile void * base,uintptr_t byteOffset)166 _OSReadInt32(
167     const volatile void               * base,
168     uintptr_t                     byteOffset
169 )
170 {
171     return *(volatile uint32_t *)((uintptr_t)base + byteOffset);
172 }
173 
174 OS_INLINE
175 uint64_t
_OSReadInt64(const volatile void * base,uintptr_t byteOffset)176 _OSReadInt64(
177     const volatile void               * base,
178     uintptr_t                     byteOffset
179 )
180 {
181     return *(volatile uint64_t *)((uintptr_t)base + byteOffset);
182 }
183 
184 /* Functions for storing native endian values. */
185 
186 OS_INLINE
187 void
_OSWriteInt16(volatile void * base,uintptr_t byteOffset,uint16_t data)188 _OSWriteInt16(
189     volatile void               * base,
190     uintptr_t                     byteOffset,
191     uint16_t                      data
192 )
193 {
194     *(volatile uint16_t *)((uintptr_t)base + byteOffset) = data;
195 }
196 
197 OS_INLINE
198 void
_OSWriteInt32(volatile void * base,uintptr_t byteOffset,uint32_t data)199 _OSWriteInt32(
200     volatile void               * base,
201     uintptr_t                     byteOffset,
202     uint32_t                      data
203 )
204 {
205     *(volatile uint32_t *)((uintptr_t)base + byteOffset) = data;
206 }
207 
208 OS_INLINE
209 void
_OSWriteInt64(volatile void * base,uintptr_t byteOffset,uint64_t data)210 _OSWriteInt64(
211     volatile void               * base,
212     uintptr_t                     byteOffset,
213     uint64_t                      data
214 )
215 {
216     *(volatile uint64_t *)((uintptr_t)base + byteOffset) = data;
217 }
218 
219 #if		defined(__BIG_ENDIAN__)
220 
221 /* Functions for loading big endian to host endianess. */
222 
223 #define OSReadBigInt16(base, byteOffset) _OSReadInt16(base, byteOffset)
224 #define OSReadBigInt32(base, byteOffset) _OSReadInt32(base, byteOffset)
225 #define OSReadBigInt64(base, byteOffset) _OSReadInt64(base, byteOffset)
226 
227 /* Functions for storing host endianess to big endian. */
228 
229 #define OSWriteBigInt16(base, byteOffset, data) _OSWriteInt16(base, byteOffset, data)
230 #define OSWriteBigInt32(base, byteOffset, data) _OSWriteInt32(base, byteOffset, data)
231 #define OSWriteBigInt64(base, byteOffset, data) _OSWriteInt64(base, byteOffset, data)
232 
233 /* Functions for loading little endian to host endianess. */
234 
235 #define OSReadLittleInt16(base, byteOffset) OSReadSwapInt16(base, byteOffset)
236 #define OSReadLittleInt32(base, byteOffset) OSReadSwapInt32(base, byteOffset)
237 #define OSReadLittleInt64(base, byteOffset) OSReadSwapInt64(base, byteOffset)
238 
239 /* Functions for storing host endianess to little endian. */
240 
241 #define OSWriteLittleInt16(base, byteOffset, data) OSWriteSwapInt16(base, byteOffset, data)
242 #define OSWriteLittleInt32(base, byteOffset, data) OSWriteSwapInt32(base, byteOffset, data)
243 #define OSWriteLittleInt64(base, byteOffset, data) OSWriteSwapInt64(base, byteOffset, data)
244 
245 /* Host endianess to big endian byte swapping macros for constants. */
246 
247 #define OSSwapHostToBigConstInt16(x) ((uint16_t)(x))
248 #define OSSwapHostToBigConstInt32(x) ((uint32_t)(x))
249 #define OSSwapHostToBigConstInt64(x) ((uint64_t)(x))
250 
251 /* Generic host endianess to big endian byte swapping functions. */
252 
253 #define OSSwapHostToBigInt16(x) ((uint16_t)(x))
254 #define OSSwapHostToBigInt32(x) ((uint32_t)(x))
255 #define OSSwapHostToBigInt64(x) ((uint64_t)(x))
256 
257 /* Host endianess to little endian byte swapping macros for constants. */
258 
259 #define OSSwapHostToLittleConstInt16(x) OSSwapConstInt16(x)
260 #define OSSwapHostToLittleConstInt32(x) OSSwapConstInt32(x)
261 #define OSSwapHostToLittleConstInt64(x) OSSwapConstInt64(x)
262 
263 /* Generic host endianess to little endian byte swapping functions. */
264 
265 #define OSSwapHostToLittleInt16(x) OSSwapInt16(x)
266 #define OSSwapHostToLittleInt32(x) OSSwapInt32(x)
267 #define OSSwapHostToLittleInt64(x) OSSwapInt64(x)
268 
269 /* Big endian to host endianess byte swapping macros for constants. */
270 
271 #define OSSwapBigToHostConstInt16(x) ((uint16_t)(x))
272 #define OSSwapBigToHostConstInt32(x) ((uint32_t)(x))
273 #define OSSwapBigToHostConstInt64(x) ((uint64_t)(x))
274 
275 /* Generic big endian to host endianess byte swapping functions. */
276 
277 #define OSSwapBigToHostInt16(x) ((uint16_t)(x))
278 #define OSSwapBigToHostInt32(x) ((uint32_t)(x))
279 #define OSSwapBigToHostInt64(x) ((uint64_t)(x))
280 
281 /* Little endian to host endianess byte swapping macros for constants. */
282 
283 #define OSSwapLittleToHostConstInt16(x) OSSwapConstInt16(x)
284 #define OSSwapLittleToHostConstInt32(x) OSSwapConstInt32(x)
285 #define OSSwapLittleToHostConstInt64(x) OSSwapConstInt64(x)
286 
287 /* Generic little endian to host endianess byte swapping functions. */
288 
289 #define OSSwapLittleToHostInt16(x) OSSwapInt16(x)
290 #define OSSwapLittleToHostInt32(x) OSSwapInt32(x)
291 #define OSSwapLittleToHostInt64(x) OSSwapInt64(x)
292 
293 #elif		defined(__LITTLE_ENDIAN__)
294 
295 /* Functions for loading big endian to host endianess. */
296 
297 #define OSReadBigInt16(base, byteOffset) OSReadSwapInt16(base, byteOffset)
298 #define OSReadBigInt32(base, byteOffset) OSReadSwapInt32(base, byteOffset)
299 #define OSReadBigInt64(base, byteOffset) OSReadSwapInt64(base, byteOffset)
300 
301 /* Functions for storing host endianess to big endian. */
302 
303 #define OSWriteBigInt16(base, byteOffset, data) OSWriteSwapInt16(base, byteOffset, data)
304 #define OSWriteBigInt32(base, byteOffset, data) OSWriteSwapInt32(base, byteOffset, data)
305 #define OSWriteBigInt64(base, byteOffset, data) OSWriteSwapInt64(base, byteOffset, data)
306 
307 /* Functions for loading little endian to host endianess. */
308 
309 #define OSReadLittleInt16(base, byteOffset) _OSReadInt16(base, byteOffset)
310 #define OSReadLittleInt32(base, byteOffset) _OSReadInt32(base, byteOffset)
311 #define OSReadLittleInt64(base, byteOffset) _OSReadInt64(base, byteOffset)
312 
313 /* Functions for storing host endianess to little endian. */
314 
315 #define OSWriteLittleInt16(base, byteOffset, data) _OSWriteInt16(base, byteOffset, data)
316 #define OSWriteLittleInt32(base, byteOffset, data) _OSWriteInt32(base, byteOffset, data)
317 #define OSWriteLittleInt64(base, byteOffset, data) _OSWriteInt64(base, byteOffset, data)
318 
319 /* Host endianess to big endian byte swapping macros for constants. */
320 
321 #define OSSwapHostToBigConstInt16(x) OSSwapConstInt16(x)
322 #define OSSwapHostToBigConstInt32(x) OSSwapConstInt32(x)
323 #define OSSwapHostToBigConstInt64(x) OSSwapConstInt64(x)
324 
325 /* Generic host endianess to big endian byte swapping functions. */
326 
327 #define OSSwapHostToBigInt16(x) OSSwapInt16(x)
328 #define OSSwapHostToBigInt32(x) OSSwapInt32(x)
329 #define OSSwapHostToBigInt64(x) OSSwapInt64(x)
330 
331 /* Host endianess to little endian byte swapping macros for constants. */
332 
333 #define OSSwapHostToLittleConstInt16(x) ((uint16_t)(x))
334 #define OSSwapHostToLittleConstInt32(x) ((uint32_t)(x))
335 #define OSSwapHostToLittleConstInt64(x) ((uint64_t)(x))
336 
337 /* Generic host endianess to little endian byte swapping functions. */
338 
339 #define OSSwapHostToLittleInt16(x) ((uint16_t)(x))
340 #define OSSwapHostToLittleInt32(x) ((uint32_t)(x))
341 #define OSSwapHostToLittleInt64(x) ((uint64_t)(x))
342 
343 /* Big endian to host endianess byte swapping macros for constants. */
344 
345 #define OSSwapBigToHostConstInt16(x) OSSwapConstInt16(x)
346 #define OSSwapBigToHostConstInt32(x) OSSwapConstInt32(x)
347 #define OSSwapBigToHostConstInt64(x) OSSwapConstInt64(x)
348 
349 /* Generic big endian to host endianess byte swapping functions. */
350 
351 #define OSSwapBigToHostInt16(x) OSSwapInt16(x)
352 #define OSSwapBigToHostInt32(x) OSSwapInt32(x)
353 #define OSSwapBigToHostInt64(x) OSSwapInt64(x)
354 
355 /* Little endian to host endianess byte swapping macros for constants. */
356 
357 #define OSSwapLittleToHostConstInt16(x) ((uint16_t)(x))
358 #define OSSwapLittleToHostConstInt32(x) ((uint32_t)(x))
359 #define OSSwapLittleToHostConstInt64(x) ((uint64_t)(x))
360 
361 /* Generic little endian to host endianess byte swapping functions. */
362 
363 #define OSSwapLittleToHostInt16(x) ((uint16_t)(x))
364 #define OSSwapLittleToHostInt32(x) ((uint32_t)(x))
365 #define OSSwapLittleToHostInt64(x) ((uint64_t)(x))
366 
367 #else
368 #error Unknown endianess.
369 #endif
370 
371 #endif /* ! _OS_OSBYTEORDER_H */
372 
373 
374