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