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