]> git.saurik.com Git - apple/xnu.git/blob - libkern/libkern/OSByteOrder.h
14acbcc8835a5376f41dec1e4023c5409ec1d92e
[apple/xnu.git] / libkern / libkern / OSByteOrder.h
1 /*
2 * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_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. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23 /*
24 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
25 *
26 * HISTORY
27 *
28 */
29
30 #ifndef _OS_OSBYTEORDER_H
31 #define _OS_OSBYTEORDER_H
32
33 #include <stdint.h>
34
35 #if defined(__GNUC__) && defined(__ppc__)
36 #include <libkern/ppc/OSByteOrder.h>
37 #elif defined(__GNUC__) && defined(__i386__)
38 #include <libkern/i386/OSByteOrder.h>
39 #else
40 #include <libkern/machine/OSByteOrder.h>
41 #endif
42
43 enum {
44 OSUnknownByteOrder,
45 OSLittleEndian,
46 OSBigEndian
47 };
48
49 OS_INLINE
50 int32_t
51 OSHostByteOrder(void) {
52 #if defined(__LITTLE_ENDIAN__)
53 return OSLittleEndian;
54 #elif defined(__BIG_ENDIAN__)
55 return OSBigEndian;
56 #else
57 return OSUnknownByteOrder;
58 #endif
59 }
60
61 /* Macros for swapping constant values in the preprocessing stage. */
62 #define OSSwapConstInt16(x) ((((uint16_t)(x) & 0xff00) >> 8) | \
63 (((uint16_t)(x) & 0x00ff) << 8))
64
65 #define OSSwapConstInt32(x) ((((uint32_t)(x) & 0xff000000) >> 24) | \
66 (((uint32_t)(x) & 0x00ff0000) >> 8) | \
67 (((uint32_t)(x) & 0x0000ff00) << 8) | \
68 (((uint32_t)(x) & 0x000000ff) << 24))
69
70 #define OSSwapConstInt64(x) ((((uint64_t)(x) & 0xff00000000000000ULL) >> 56) | \
71 (((uint64_t)(x) & 0x00ff000000000000ULL) >> 40) | \
72 (((uint64_t)(x) & 0x0000ff0000000000ULL) >> 24) | \
73 (((uint64_t)(x) & 0x000000ff00000000ULL) >> 8) | \
74 (((uint64_t)(x) & 0x00000000ff000000ULL) << 8) | \
75 (((uint64_t)(x) & 0x0000000000ff0000ULL) << 24) | \
76 (((uint64_t)(x) & 0x000000000000ff00ULL) << 40) | \
77 (((uint64_t)(x) & 0x00000000000000ffULL) << 56))
78
79 #if !defined(__GNUC__)
80 #define __builtin_constant_p(x) (0)
81 #endif
82
83 #define OSSwapInt16(x) \
84 (__builtin_constant_p(x) ? OSSwapConstInt16(x) : _OSSwapInt16(x))
85
86 #define OSSwapInt32(x) \
87 (__builtin_constant_p(x) ? OSSwapConstInt32(x) : _OSSwapInt32(x))
88
89 #define OSSwapInt64(x) \
90 (__builtin_constant_p(x) ? OSSwapConstInt64(x) : _OSSwapInt64(x))
91
92 #define OSReadBigInt(x, y) OSReadBigInt32(x, y)
93 #define OSWriteBigInt(x, y, z) OSWriteBigInt32(x, y, z)
94 #define OSSwapBigToHostInt(x) OSSwapBigToHostInt32(x)
95 #define OSSwapHostToBigInt(x) OSSwapHostToBigInt32(x)
96 #define OSReadLittleInt(x, y) OSReadLittleInt32(x, y)
97 #define OSWriteLittleInt(x, y, z) OSWriteLittleInt32(x, y, z)
98 #define OSSwapHostToLittleInt(x) OSSwapHostToLittleInt32(x)
99 #define OSSwapLittleToHostInt(x) OSSwapLittleToHostInt32(x)
100
101 #if defined(__BIG_ENDIAN__)
102
103 /* Functions for loading big endian to host endianess. */
104
105 OS_INLINE
106 uint16_t
107 OSReadBigInt16(
108 const volatile void * base,
109 uintptr_t offset
110 )
111 {
112 return *(volatile uint16_t *)((uintptr_t)base + offset);
113 }
114
115 OS_INLINE
116 uint32_t
117 OSReadBigInt32(
118 const volatile void * base,
119 uintptr_t offset
120 )
121 {
122 return *(volatile uint32_t *)((uintptr_t)base + offset);
123 }
124
125 OS_INLINE
126 uint64_t
127 OSReadBigInt64(
128 const volatile void * base,
129 uintptr_t offset
130 )
131 {
132 return *(volatile uint64_t *)((uintptr_t)base + offset);
133 }
134
135 /* Functions for storing host endianess to big endian. */
136
137 OS_INLINE
138 void
139 OSWriteBigInt16(
140 volatile void * base,
141 uintptr_t offset,
142 uint16_t data
143 )
144 {
145 *(volatile uint16_t *)((uintptr_t)base + offset) = data;
146 }
147
148 OS_INLINE
149 void
150 OSWriteBigInt32(
151 volatile void * base,
152 uintptr_t offset,
153 uint32_t data
154 )
155 {
156 *(volatile uint32_t *)((uintptr_t)base + offset) = data;
157 }
158
159 OS_INLINE
160 void
161 OSWriteBigInt64(
162 volatile void * base,
163 uintptr_t offset,
164 uint64_t data
165 )
166 {
167 *(volatile uint64_t *)((uintptr_t)base + offset) = data;
168 }
169
170 /* Functions for loading little endian to host endianess. */
171
172 OS_INLINE
173 uint16_t
174 OSReadLittleInt16(
175 volatile void * base,
176 uintptr_t offset
177 )
178 {
179 return OSReadSwapInt16(base, offset);
180 }
181
182 OS_INLINE
183 uint32_t
184 OSReadLittleInt32(
185 volatile void * base,
186 uintptr_t offset
187 )
188 {
189 return OSReadSwapInt32(base, offset);
190 }
191
192 OS_INLINE
193 uint64_t
194 OSReadLittleInt64(
195 volatile void * base,
196 uintptr_t offset
197 )
198 {
199 return OSReadSwapInt64(base, offset);
200 }
201
202 /* Functions for storing host endianess to little endian. */
203
204 OS_INLINE
205 void
206 OSWriteLittleInt16(
207 volatile void * base,
208 uintptr_t offset,
209 uint16_t data
210 )
211 {
212 OSWriteSwapInt16(base, offset, data);
213 }
214
215 OS_INLINE
216 void
217 OSWriteLittleInt32(
218 volatile void * base,
219 uintptr_t offset,
220 uint32_t data
221 )
222 {
223 OSWriteSwapInt32(base, offset, data);
224 }
225
226 OS_INLINE
227 void
228 OSWriteLittleInt64(
229 volatile void * base,
230 uintptr_t offset,
231 uint64_t data
232 )
233 {
234 OSWriteSwapInt64(base, offset, data);
235 }
236
237 /* Host endianess to big endian byte swapping macros for constants. */
238
239 #define OSSwapHostToBigConstInt16(x) (x)
240 #define OSSwapHostToBigConstInt32(x) (x)
241 #define OSSwapHostToBigConstInt64(x) (x)
242
243 /* Generic host endianess to big endian byte swapping functions. */
244
245 OS_INLINE
246 uint16_t
247 OSSwapHostToBigInt16(
248 uint16_t data
249 )
250 {
251 return data;
252 }
253
254 OS_INLINE
255 uint32_t
256 OSSwapHostToBigInt32(
257 uint32_t data
258 )
259 {
260 return data;
261 }
262
263 OS_INLINE
264 uint64_t
265 OSSwapHostToBigInt64(
266 uint64_t data
267 )
268 {
269 return data;
270 }
271
272 /* Host endianess to little endian byte swapping macros for constants. */
273
274 #define OSSwapHostToLittleConstInt16(x) OSSwapConstInt16(x)
275 #define OSSwapHostToLittleConstInt32(x) OSSwapConstInt32(x)
276 #define OSSwapHostToLittleConstInt64(x) OSSwapConstInt64(x)
277
278 /* Generic host endianess to little endian byte swapping functions. */
279
280 #define OSSwapHostToLittleInt16(x) OSSwapInt16(x)
281 #define OSSwapHostToLittleInt32(x) OSSwapInt32(x)
282 #define OSSwapHostToLittleInt64(x) OSSwapInt64(x)
283
284 /* Big endian to host endianess byte swapping macros for constants. */
285
286 #define OSSwapBigToHostConstInt16(x) (x)
287 #define OSSwapBigToHostConstInt32(x) (x)
288 #define OSSwapBigToHostConstInt64(x) (x)
289
290 /* Generic big endian to host endianess byte swapping functions. */
291
292 OS_INLINE
293 uint16_t
294 OSSwapBigToHostInt16(
295 uint16_t data
296 )
297 {
298 return data;
299 }
300
301 OS_INLINE
302 uint32_t
303 OSSwapBigToHostInt32(
304 uint32_t data
305 )
306 {
307 return data;
308 }
309
310 OS_INLINE
311 uint64_t
312 OSSwapBigToHostInt64(
313 uint64_t data
314 )
315 {
316 return data;
317 }
318
319 /* Little endian to host endianess byte swapping macros for constants. */
320
321 #define OSSwapLittleToHostConstInt16(x) OSSwapConstInt16(x)
322 #define OSSwapLittleToHostConstInt32(x) OSSwapConstInt32(x)
323 #define OSSwapLittleToHostConstInt64(x) OSSwapConstInt64(x)
324
325 /* Generic little endian to host endianess byte swapping functions. */
326
327 #define OSSwapLittleToHostInt16(x) OSSwapInt16(x)
328 #define OSSwapLittleToHostInt32(x) OSSwapInt32(x)
329 #define OSSwapLittleToHostInt64(x) OSSwapInt64(x)
330
331 #elif defined(__LITTLE_ENDIAN__)
332
333 /* Functions for loading big endian to host endianess. */
334
335 OS_INLINE
336 uint16_t
337 OSReadBigInt16(
338 const volatile void * base,
339 uintptr_t offset
340 )
341 {
342 return OSReadSwapInt16(base, offset);
343 }
344
345 OS_INLINE
346 uint32_t
347 OSReadBigInt32(
348 const volatile void * base,
349 uintptr_t offset
350 )
351 {
352 return OSReadSwapInt32(base, offset);
353 }
354
355 OS_INLINE
356 uint64_t
357 OSReadBigInt64(
358 const volatile void * base,
359 uintptr_t offset
360 )
361 {
362 return OSReadSwapInt64(base, offset);
363 }
364
365 /* Functions for storing host endianess to big endian. */
366
367 OS_INLINE
368 void
369 OSWriteBigInt16(
370 volatile void * base,
371 uintptr_t offset,
372 uint16_t data
373 )
374 {
375 OSWriteSwapInt16(base, offset, data);
376 }
377
378 OS_INLINE
379 void
380 OSWriteBigInt32(
381 volatile void * base,
382 uintptr_t offset,
383 uint32_t data
384 )
385 {
386 OSWriteSwapInt32(base, offset, data);
387 }
388
389 OS_INLINE
390 void
391 OSWriteBigInt64(
392 volatile void * base,
393 uintptr_t offset,
394 uint64_t data
395 )
396 {
397 OSWriteSwapInt64(base, offset, data);
398 }
399
400 /* Functions for loading little endian to host endianess. */
401
402 OS_INLINE
403 uint16_t
404 OSReadLittleInt16(
405 const volatile void * base,
406 uintptr_t offset
407 )
408 {
409 return *(volatile uint16_t *)((uintptr_t)base + offset);
410 }
411
412 OS_INLINE
413 uint32_t
414 OSReadLittleInt32(
415 const volatile void * base,
416 uintptr_t offset
417 )
418 {
419 return *(volatile uint32_t *)((uintptr_t)base + offset);
420 }
421
422 OS_INLINE
423 uint64_t
424 OSReadLittleInt64(
425 const volatile void * base,
426 uintptr_t offset
427 )
428 {
429 return *(volatile uint64_t *)((uintptr_t)base + offset);
430 }
431
432 /* Functions for storing host endianess to little endian. */
433
434 OS_INLINE
435 void
436 OSWriteLittleInt16(
437 volatile void * base,
438 uintptr_t offset,
439 uint16_t data
440 )
441 {
442 *(volatile uint16_t *)((uintptr_t)base + offset) = data;
443 }
444
445 OS_INLINE
446 void
447 OSWriteLittleInt32(
448 volatile void * base,
449 uintptr_t offset,
450 uint32_t data
451 )
452 {
453 *(volatile uint32_t *)((uintptr_t)base + offset) = data;
454 }
455
456 OS_INLINE
457 void
458 OSWriteLittleInt64(
459 volatile void * base,
460 uintptr_t offset,
461 uint64_t data
462 )
463 {
464 *(volatile uint64_t *)((uintptr_t)base + offset) = data;
465 }
466
467 /* Host endianess to big endian byte swapping macros for constants. */
468
469 #define OSSwapHostToBigConstInt16(x) OSSwapConstInt16(x)
470 #define OSSwapHostToBigConstInt32(x) OSSwapConstInt32(x)
471 #define OSSwapHostToBigConstInt64(x) OSSwapConstInt64(x)
472
473 /* Generic host endianess to big endian byte swapping functions. */
474
475 #define OSSwapHostToBigInt16(x) OSSwapInt16(x)
476 #define OSSwapHostToBigInt32(x) OSSwapInt32(x)
477 #define OSSwapHostToBigInt64(x) OSSwapInt64(x)
478
479 /* Host endianess to little endian byte swapping macros for constants. */
480
481 #define OSSwapHostToLittleConstInt16(x) (x)
482 #define OSSwapHostToLittleConstInt32(x) (x)
483 #define OSSwapHostToLittleConstInt64(x) (x)
484
485 /* Generic host endianess to little endian byte swapping functions. */
486
487 OS_INLINE
488 uint16_t
489 OSSwapHostToLittleInt16(
490 uint16_t data
491 )
492 {
493 return data;
494 }
495
496 OS_INLINE
497 uint32_t
498 OSSwapHostToLittleInt32(
499 uint32_t data
500 )
501 {
502 return data;
503 }
504
505 OS_INLINE
506 uint64_t
507 OSSwapHostToLittleInt64(
508 uint64_t data
509 )
510 {
511 return data;
512 }
513
514 /* Big endian to host endianess byte swapping macros for constants. */
515
516 #define OSSwapBigToHostConstInt16(x) OSSwapConstInt16(x)
517 #define OSSwapBigToHostConstInt32(x) OSSwapConstInt32(x)
518 #define OSSwapBigToHostConstInt64(x) OSSwapConstInt64(x)
519
520 /* Generic big endian to host endianess byte swapping functions. */
521
522 #define OSSwapBigToHostInt16(x) OSSwapInt16(x)
523 #define OSSwapBigToHostInt32(x) OSSwapInt32(x)
524 #define OSSwapBigToHostInt64(x) OSSwapInt64(x)
525
526 /* Little endian to host endianess byte swapping macros for constants. */
527
528 #define OSSwapLittleToHostConstInt16(x) (x)
529 #define OSSwapLittleToHostConstInt32(x) (x)
530 #define OSSwapLittleToHostConstInt64(x) (x)
531
532 /* Generic little endian to host endianess byte swapping functions. */
533
534 OS_INLINE
535 uint16_t
536 OSSwapLittleToHostInt16(
537 uint16_t data
538 )
539 {
540 return data;
541 }
542
543 OS_INLINE
544 uint32_t
545 OSSwapLittleToHostInt32(
546 uint32_t data
547 )
548 {
549 return data;
550 }
551
552 OS_INLINE
553 uint64_t
554 OSSwapLittleToHostInt64(
555 uint64_t data
556 )
557 {
558 return data;
559 }
560
561 #else
562 #error Unknown endianess.
563 #endif
564
565 #endif /* ! _OS_OSBYTEORDER_H */
566
567