]> git.saurik.com Git - apple/xnu.git/blob - libkern/libkern/ppc/OSByteOrder.h
e545f5236ac368b778f45f4daa6cc9f8fbb5b2f8
[apple/xnu.git] / libkern / libkern / ppc / OSByteOrder.h
1 /*
2 * Copyright (c) 2000-2005 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 #ifndef _OS_OSBYTEORDERPPC_H
24 #define _OS_OSBYTEORDERPPC_H
25
26 #include <stdint.h>
27
28 #if !defined(OS_INLINE)
29 # if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
30 # define OS_INLINE static inline
31 # elif defined(__MWERKS__) || defined(__cplusplus)
32 # define OS_INLINE static inline
33 # else
34 # define OS_INLINE static __inline__
35 # endif
36 #endif
37
38 /* Functions for byte reversed loads. */
39
40 OS_INLINE
41 uint16_t
42 OSReadSwapInt16(
43 const volatile void * base,
44 uintptr_t byteOffset
45 )
46 {
47 uint16_t result;
48 volatile uint16_t *addr = (volatile uint16_t *)((uintptr_t)base + byteOffset);
49
50 __asm__ ("lhbrx %0, %2, %1"
51 : "=r" (result)
52 : "r" (base), "bO" (byteOffset), "m" (*addr));
53 return result;
54 }
55
56 OS_INLINE
57 uint32_t
58 OSReadSwapInt32(
59 const volatile void * base,
60 uintptr_t byteOffset
61 )
62 {
63 uint32_t result;
64 volatile uint32_t *addr = (volatile uint32_t *)((uintptr_t)base + byteOffset);
65
66 __asm__ ("lwbrx %0, %2, %1"
67 : "=r" (result)
68 : "r" (base), "bO" (byteOffset), "m" (*addr));
69 return result;
70 }
71
72 OS_INLINE
73 uint64_t
74 OSReadSwapInt64(
75 const volatile void * base,
76 uintptr_t byteOffset
77 )
78 {
79 volatile uint64_t *addr = (volatile uint64_t *)((uintptr_t)base + byteOffset);
80 union {
81 uint64_t u64;
82 uint32_t u32[2];
83 } u;
84
85 __asm__ ("lwbrx %0, %3, %2\n\t"
86 "lwbrx %1, %4, %2"
87 : "=&r" (u.u32[1]), "=r" (u.u32[0])
88 : "r" (base), "bO" (byteOffset), "b" (byteOffset + 4), "m" (*addr));
89 return u.u64;
90 }
91
92 /* Functions for byte reversed stores. */
93
94 OS_INLINE
95 void
96 OSWriteSwapInt16(
97 volatile void * base,
98 uintptr_t byteOffset,
99 uint16_t data
100 )
101 {
102 volatile uint16_t *addr = (volatile uint16_t *)((uintptr_t)base + byteOffset);
103
104 __asm__ ("sthbrx %1, %3, %2"
105 : "=m" (*addr)
106 : "r" (data), "r" (base), "bO" (byteOffset));
107 }
108
109 OS_INLINE
110 void
111 OSWriteSwapInt32(
112 volatile void * base,
113 uintptr_t byteOffset,
114 uint32_t data
115 )
116 {
117 volatile uint32_t *addr = (volatile uint32_t *)((uintptr_t)base + byteOffset);
118
119 __asm__ ("stwbrx %1, %3, %2"
120 : "=m" (*addr)
121 : "r" (data), "r" (base), "bO" (byteOffset));
122 }
123
124 OS_INLINE
125 void
126 OSWriteSwapInt64(
127 volatile void * base,
128 uintptr_t byteOffset,
129 uint64_t data
130 )
131 {
132 volatile uint64_t *addr = (volatile uint64_t *)((uintptr_t)base + byteOffset);
133 uint32_t hi = data >> 32;
134 uint32_t lo = data & 0xffffffff;
135
136 __asm__ ("stwbrx %1, %4, %3\n\t"
137 "stwbrx %2, %5, %3"
138 : "=m" (*addr)
139 : "r" (lo), "r" (hi), "r" (base), "bO" (byteOffset), "b" (byteOffset + 4));
140 }
141
142 /* Generic byte swapping functions. */
143
144 OS_INLINE
145 uint16_t
146 _OSSwapInt16(
147 uint16_t data
148 )
149 {
150 return OSReadSwapInt16(&data, 0);
151 }
152
153 OS_INLINE
154 uint32_t
155 _OSSwapInt32(
156 uint32_t data
157 )
158 {
159 return OSReadSwapInt32(&data, 0);
160 }
161
162 OS_INLINE
163 uint64_t
164 _OSSwapInt64(
165 uint64_t data
166 )
167 {
168 return OSReadSwapInt64(&data, 0);
169 }
170
171 #endif /* ! _OS_OSBYTEORDERPPC_H */