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