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#if !defined(__DARWIN_OS_INLINE)
41# if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
42# define __DARWIN_OS_INLINE static inline
43# elif defined(__MWERKS__) || defined(__cplusplus)
44# define __DARWIN_OS_INLINE static inline
45# else
46# define __DARWIN_OS_INLINE static __inline__
47# endif
48#endif
49
50#if defined(__GNUC__)
51
52#if (defined(__i386__) || defined(__x86_64__))
53#include <libkern/i386/OSByteOrder.h>
54#elif defined (__arm__) || defined(__arm64__)
55#include <libkern/arm/OSByteOrder.h>
56#else
57#include <libkern/machine/OSByteOrder.h>
58#endif
59
60#else /* ! __GNUC__ */
61
62#include <libkern/machine/OSByteOrder.h>
63
64#endif /* __GNUC__ */
65
66#define OSSwapInt16(x) __DARWIN_OSSwapInt16(x)
67#define OSSwapInt32(x) __DARWIN_OSSwapInt32(x)
68#define OSSwapInt64(x) __DARWIN_OSSwapInt64(x)
69
70enum {
71 OSUnknownByteOrder,
72 OSLittleEndian,
73 OSBigEndian
74};
75
76__DARWIN_OS_INLINE
77int32_t
78OSHostByteOrder(void)
79{
80#if defined(__LITTLE_ENDIAN__)
81 return OSLittleEndian;
82#elif defined(__BIG_ENDIAN__)
83 return OSBigEndian;
84#else
85 return OSUnknownByteOrder;
86#endif
87}
88
89#define OSReadBigInt(x, y) OSReadBigInt32(x, y)
90#define OSWriteBigInt(x, y, z) OSWriteBigInt32(x, y, z)
91#define OSSwapBigToHostInt(x) OSSwapBigToHostInt32(x)
92#define OSSwapHostToBigInt(x) OSSwapHostToBigInt32(x)
93#define OSReadLittleInt(x, y) OSReadLittleInt32(x, y)
94#define OSWriteLittleInt(x, y, z) OSWriteLittleInt32(x, y, z)
95#define OSSwapHostToLittleInt(x) OSSwapHostToLittleInt32(x)
96#define OSSwapLittleToHostInt(x) OSSwapLittleToHostInt32(x)
97
98/* Functions for loading native endian values. */
99
100__DARWIN_OS_INLINE
101uint16_t
102_OSReadInt16(
103 const volatile void * base,
104 uintptr_t byteOffset
105 )
106{
107 return *(volatile uint16_t *)((uintptr_t)base + byteOffset);
108}
109
110__DARWIN_OS_INLINE
111uint32_t
112_OSReadInt32(
113 const volatile void * base,
114 uintptr_t byteOffset
115 )
116{
117 return *(volatile uint32_t *)((uintptr_t)base + byteOffset);
118}
119
120__DARWIN_OS_INLINE
121uint64_t
122_OSReadInt64(
123 const volatile void * base,
124 uintptr_t byteOffset
125 )
126{
127 return *(volatile uint64_t *)((uintptr_t)base + byteOffset);
128}
129
130/* Functions for storing native endian values. */
131
132__DARWIN_OS_INLINE
133void
134_OSWriteInt16(
135 volatile void * base,
136 uintptr_t byteOffset,
137 uint16_t data
138 )
139{
140 *(volatile uint16_t *)((uintptr_t)base + byteOffset) = data;
141}
142
143__DARWIN_OS_INLINE
144void
145_OSWriteInt32(
146 volatile void * base,
147 uintptr_t byteOffset,
148 uint32_t data
149 )
150{
151 *(volatile uint32_t *)((uintptr_t)base + byteOffset) = data;
152}
153
154__DARWIN_OS_INLINE
155void
156_OSWriteInt64(
157 volatile void * base,
158 uintptr_t byteOffset,
159 uint64_t data
160 )
161{
162 *(volatile uint64_t *)((uintptr_t)base + byteOffset) = data;
163}
164
165#if defined(__BIG_ENDIAN__)
166
167/* Functions for loading big endian to host endianess. */
168
169#define OSReadBigInt16(base, byteOffset) _OSReadInt16(base, byteOffset)
170#define OSReadBigInt32(base, byteOffset) _OSReadInt32(base, byteOffset)
171#define OSReadBigInt64(base, byteOffset) _OSReadInt64(base, byteOffset)
172
173/* Functions for storing host endianess to big endian. */
174
175#define OSWriteBigInt16(base, byteOffset, data) _OSWriteInt16(base, byteOffset, data)
176#define OSWriteBigInt32(base, byteOffset, data) _OSWriteInt32(base, byteOffset, data)
177#define OSWriteBigInt64(base, byteOffset, data) _OSWriteInt64(base, byteOffset, data)
178
179/* Functions for loading little endian to host endianess. */
180
181#define OSReadLittleInt16(base, byteOffset) OSReadSwapInt16(base, byteOffset)
182#define OSReadLittleInt32(base, byteOffset) OSReadSwapInt32(base, byteOffset)
183#define OSReadLittleInt64(base, byteOffset) OSReadSwapInt64(base, byteOffset)
184
185/* Functions for storing host endianess to little endian. */
186
187#define OSWriteLittleInt16(base, byteOffset, data) OSWriteSwapInt16(base, byteOffset, data)
188#define OSWriteLittleInt32(base, byteOffset, data) OSWriteSwapInt32(base, byteOffset, data)
189#define OSWriteLittleInt64(base, byteOffset, data) OSWriteSwapInt64(base, byteOffset, data)
190
191/* Host endianess to big endian byte swapping macros for constants. */
192
193#define OSSwapHostToBigConstInt16(x) ((uint16_t)(x))
194#define OSSwapHostToBigConstInt32(x) ((uint32_t)(x))
195#define OSSwapHostToBigConstInt64(x) ((uint64_t)(x))
196
197/* Generic host endianess to big endian byte swapping functions. */
198
199#define OSSwapHostToBigInt16(x) ((uint16_t)(x))
200#define OSSwapHostToBigInt32(x) ((uint32_t)(x))
201#define OSSwapHostToBigInt64(x) ((uint64_t)(x))
202
203/* Host endianess to little endian byte swapping macros for constants. */
204
205#define OSSwapHostToLittleConstInt16(x) OSSwapConstInt16(x)
206#define OSSwapHostToLittleConstInt32(x) OSSwapConstInt32(x)
207#define OSSwapHostToLittleConstInt64(x) OSSwapConstInt64(x)
208
209/* Generic host endianess to little endian byte swapping functions. */
210
211#define OSSwapHostToLittleInt16(x) OSSwapInt16(x)
212#define OSSwapHostToLittleInt32(x) OSSwapInt32(x)
213#define OSSwapHostToLittleInt64(x) OSSwapInt64(x)
214
215/* Big endian to host endianess byte swapping macros for constants. */
216
217#define OSSwapBigToHostConstInt16(x) ((uint16_t)(x))
218#define OSSwapBigToHostConstInt32(x) ((uint32_t)(x))
219#define OSSwapBigToHostConstInt64(x) ((uint64_t)(x))
220
221/* Generic big endian to host endianess byte swapping functions. */
222
223#define OSSwapBigToHostInt16(x) ((uint16_t)(x))
224#define OSSwapBigToHostInt32(x) ((uint32_t)(x))
225#define OSSwapBigToHostInt64(x) ((uint64_t)(x))
226
227/* Little endian to host endianess byte swapping macros for constants. */
228
229#define OSSwapLittleToHostConstInt16(x) OSSwapConstInt16(x)
230#define OSSwapLittleToHostConstInt32(x) OSSwapConstInt32(x)
231#define OSSwapLittleToHostConstInt64(x) OSSwapConstInt64(x)
232
233/* Generic little endian to host endianess byte swapping functions. */
234
235#define OSSwapLittleToHostInt16(x) OSSwapInt16(x)
236#define OSSwapLittleToHostInt32(x) OSSwapInt32(x)
237#define OSSwapLittleToHostInt64(x) OSSwapInt64(x)
238
239#elif defined(__LITTLE_ENDIAN__)
240
241/* Functions for loading big endian to host endianess. */
242
243#define OSReadBigInt16(base, byteOffset) OSReadSwapInt16(base, byteOffset)
244#define OSReadBigInt32(base, byteOffset) OSReadSwapInt32(base, byteOffset)
245#define OSReadBigInt64(base, byteOffset) OSReadSwapInt64(base, byteOffset)
246
247/* Functions for storing host endianess to big endian. */
248
249#define OSWriteBigInt16(base, byteOffset, data) OSWriteSwapInt16(base, byteOffset, data)
250#define OSWriteBigInt32(base, byteOffset, data) OSWriteSwapInt32(base, byteOffset, data)
251#define OSWriteBigInt64(base, byteOffset, data) OSWriteSwapInt64(base, byteOffset, data)
252
253/* Functions for loading little endian to host endianess. */
254
255#define OSReadLittleInt16(base, byteOffset) _OSReadInt16(base, byteOffset)
256#define OSReadLittleInt32(base, byteOffset) _OSReadInt32(base, byteOffset)
257#define OSReadLittleInt64(base, byteOffset) _OSReadInt64(base, byteOffset)
258
259/* Functions for storing host endianess to little endian. */
260
261#define OSWriteLittleInt16(base, byteOffset, data) _OSWriteInt16(base, byteOffset, data)
262#define OSWriteLittleInt32(base, byteOffset, data) _OSWriteInt32(base, byteOffset, data)
263#define OSWriteLittleInt64(base, byteOffset, data) _OSWriteInt64(base, byteOffset, data)
264
265/* Host endianess to big endian byte swapping macros for constants. */
266
267#define OSSwapHostToBigConstInt16(x) OSSwapConstInt16(x)
268#define OSSwapHostToBigConstInt32(x) OSSwapConstInt32(x)
269#define OSSwapHostToBigConstInt64(x) OSSwapConstInt64(x)
270
271/* Generic host endianess to big endian byte swapping functions. */
272
273#define OSSwapHostToBigInt16(x) OSSwapInt16(x)
274#define OSSwapHostToBigInt32(x) OSSwapInt32(x)
275#define OSSwapHostToBigInt64(x) OSSwapInt64(x)
276
277/* Host endianess to little endian byte swapping macros for constants. */
278
279#define OSSwapHostToLittleConstInt16(x) ((uint16_t)(x))
280#define OSSwapHostToLittleConstInt32(x) ((uint32_t)(x))
281#define OSSwapHostToLittleConstInt64(x) ((uint64_t)(x))
282
283/* Generic host endianess to little endian byte swapping functions. */
284
285#define OSSwapHostToLittleInt16(x) ((uint16_t)(x))
286#define OSSwapHostToLittleInt32(x) ((uint32_t)(x))
287#define OSSwapHostToLittleInt64(x) ((uint64_t)(x))
288
289/* Big endian to host endianess byte swapping macros for constants. */
290
291#define OSSwapBigToHostConstInt16(x) OSSwapConstInt16(x)
292#define OSSwapBigToHostConstInt32(x) OSSwapConstInt32(x)
293#define OSSwapBigToHostConstInt64(x) OSSwapConstInt64(x)
294
295/* Generic big endian to host endianess byte swapping functions. */
296
297#define OSSwapBigToHostInt16(x) OSSwapInt16(x)
298#define OSSwapBigToHostInt32(x) OSSwapInt32(x)
299#define OSSwapBigToHostInt64(x) OSSwapInt64(x)
300
301/* Little endian to host endianess byte swapping macros for constants. */
302
303#define OSSwapLittleToHostConstInt16(x) ((uint16_t)(x))
304#define OSSwapLittleToHostConstInt32(x) ((uint32_t)(x))
305#define OSSwapLittleToHostConstInt64(x) ((uint64_t)(x))
306
307/* Generic little endian to host endianess byte swapping functions. */
308
309#define OSSwapLittleToHostInt16(x) ((uint16_t)(x))
310#define OSSwapLittleToHostInt32(x) ((uint32_t)(x))
311#define OSSwapLittleToHostInt64(x) ((uint64_t)(x))
312
313#else
314#error Unknown endianess.
315#endif
316
317#endif /* ! _OS_OSBYTEORDER_H */
318