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