]> git.saurik.com Git - apple/xnu.git/blob - libkern/libkern/i386/OSByteOrder.h
dee9f11b879003f22e3308bbe8c3051c27eed1db
[apple/xnu.git] / libkern / libkern / i386 / OSByteOrder.h
1 /*
2 * Copyright (c) 1999-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 #ifndef _OS_OSBYTEORDERI386_H
25 #define _OS_OSBYTEORDERI386_H
26
27 #include <stdint.h>
28
29 #if !defined(OS_INLINE)
30 # define OS_INLINE static inline
31 #endif
32
33 /* Generic byte swapping functions. */
34
35 OS_INLINE
36 uint16_t
37 _OSSwapInt16(
38 uint16_t data
39 )
40 {
41 __asm__ ("xchgb %b0, %h0" : "+q" (data));
42 return data;
43 }
44
45 OS_INLINE
46 uint32_t
47 _OSSwapInt32(
48 uint32_t data
49 )
50 {
51 __asm__ ("bswap %0" : "+r" (data));
52 return data;
53 }
54
55 OS_INLINE
56 uint64_t
57 _OSSwapInt64(
58 uint64_t data
59 )
60 {
61 union {
62 uint64_t ull;
63 uint32_t ul[2];
64 } u;
65
66 /* This actually generates the best code */
67 u.ul[0] = data >> 32;
68 u.ul[1] = data & 0xffffffff;
69 u.ul[0] = _OSSwapInt32(u.ul[0]);
70 u.ul[1] = _OSSwapInt32(u.ul[1]);
71 return u.ull;
72 }
73
74 /* Functions for byte reversed loads. */
75
76 OS_INLINE
77 uint16_t
78 OSReadSwapInt16(
79 const volatile void * base,
80 uintptr_t offset
81 )
82 {
83 uint16_t result;
84
85 result = *(volatile uint16_t *)((uintptr_t)base + offset);
86 return _OSSwapInt16(result);
87 }
88
89 OS_INLINE
90 uint32_t
91 OSReadSwapInt32(
92 const volatile void * base,
93 uintptr_t offset
94 )
95 {
96 uint32_t result;
97
98 result = *(volatile uint32_t *)((uintptr_t)base + offset);
99 return _OSSwapInt32(result);
100 }
101
102 OS_INLINE
103 uint64_t
104 OSReadSwapInt64(
105 const volatile void * base,
106 uintptr_t offset
107 )
108 {
109 const volatile uint32_t * inp;
110 union ullc {
111 uint64_t ull;
112 uint32_t ul[2];
113 } outv;
114
115 inp = (const volatile uint32_t *)((uintptr_t)base + offset);
116 outv.ul[0] = inp[1];
117 outv.ul[1] = inp[0];
118 outv.ul[0] = _OSSwapInt32(outv.ul[0]);
119 outv.ul[1] = _OSSwapInt32(outv.ul[1]);
120 return outv.ull;
121 }
122
123 /* Functions for byte reversed stores. */
124
125 OS_INLINE
126 void
127 OSWriteSwapInt16(
128 volatile void * base,
129 uintptr_t offset,
130 uint16_t data
131 )
132 {
133 *(volatile uint16_t *)((uintptr_t)base + offset) = _OSSwapInt16(data);
134 }
135
136 OS_INLINE
137 void
138 OSWriteSwapInt32(
139 volatile void * base,
140 uintptr_t offset,
141 uint32_t data
142 )
143 {
144 *(volatile uint32_t *)((uintptr_t)base + offset) = _OSSwapInt32(data);
145 }
146
147 OS_INLINE
148 void
149 OSWriteSwapInt64(
150 volatile void * base,
151 uintptr_t offset,
152 uint64_t data
153 )
154 {
155 *(volatile uint64_t *)((uintptr_t)base + offset) = _OSSwapInt64(data);
156 }
157
158 #endif /* ! _OS_OSBYTEORDERI386_H */