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