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