]>
Commit | Line | Data |
---|---|---|
59e0d9fe A |
1 | /* |
2 | * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. | |
3 | * | |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
59e0d9fe A |
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 | #define __APPLE_API_PRIVATE | |
25 | #include <machine/cpu_capabilities.h> | |
26 | #undef __APPLE_API_PRIVATE | |
27 | ||
28 | #include <architecture/ppc/mode_independent_asm.h> | |
29 | ||
30 | ||
31 | /* These are the functions in <libkern/OSAtomic.h>. | |
32 | * The actual primitives are implemented on the commpage. | |
33 | */ | |
34 | ||
35 | ||
36 | /* int32_t OSAtomicAdd32( int32_t theAmount, int32_t *theValue ); */ | |
37 | ||
38 | MI_ENTRY_POINT(_OSAtomicAdd32) | |
39 | ba _COMM_PAGE_ATOMIC_ADD32 | |
40 | ||
41 | ||
42 | /* int32_t OSAtomicOr32( int32_t theMask, int32_t *theValue ); */ | |
43 | ||
44 | MI_ENTRY_POINT(_OSAtomicOr32) | |
45 | mflr r12 // save return address | |
46 | mr r5,r4 // move ptr to where compare-and-swap wants it | |
47 | mr r11,r3 // copy mask | |
48 | 1: | |
49 | lwz r3,0(r5) // get old value | |
50 | or r4,r3,r11 // make new value | |
51 | bla _COMM_PAGE_COMPARE_AND_SWAP32 // preserves r4,r5,r9-r12 | |
52 | cmpwi r3,0 // did swap occur? | |
53 | beq-- 1b // compare-and-swap failed, try again | |
54 | mtlr r12 // restore return adddress | |
55 | mr r3,r4 // return new value | |
56 | blr | |
57 | ||
58 | ||
59 | /* int32_t OSAtomicAnd32( int32_t theMask, int32_t *theValue ); */ | |
60 | ||
61 | MI_ENTRY_POINT(_OSAtomicAnd32) | |
62 | mflr r12 // save return address | |
63 | mr r5,r4 // move ptr to where compare-and-swap wants it | |
64 | mr r11,r3 // copy mask | |
65 | 1: | |
66 | lwz r3,0(r5) // get old value | |
67 | and r4,r3,r11 // make new value | |
68 | bla _COMM_PAGE_COMPARE_AND_SWAP32 // preserves r4,r5,r9-r12 | |
69 | cmpwi r3,0 // did swap occur? | |
70 | beq-- 1b // compare-and-swap failed, try again | |
71 | mtlr r12 // restore return adddress | |
72 | mr r3,r4 // return new value | |
73 | blr | |
74 | ||
75 | ||
76 | /* int32_t OSAtomicXor32( int32_t theMask, int32_t *theValue ); */ | |
77 | ||
78 | MI_ENTRY_POINT(_OSAtomicXor32) | |
79 | mflr r12 // save return address | |
80 | mr r5,r4 // move ptr to where compare-and-swap wants it | |
81 | mr r11,r3 // copy mask | |
82 | 1: | |
83 | lwz r3,0(r5) // get old value | |
84 | xor r4,r3,r11 // make new value | |
85 | bla _COMM_PAGE_COMPARE_AND_SWAP32 // preserves r4,r5,r9-r12 | |
86 | cmpwi r3,0 // did swap occur? | |
87 | beq-- 1b // compare-and-swap failed, try again | |
88 | mtlr r12 // restore return adddress | |
89 | mr r3,r4 // return new value | |
90 | blr | |
91 | ||
92 | ||
93 | /* int64_t OSAtomicAdd64( int64_t theAmount, int64_t *theValue ); */ | |
94 | ||
95 | #if defined(__ppc64__) | |
96 | MI_ENTRY_POINT(_OSAtomicAdd64) | |
97 | ba _COMM_PAGE_ATOMIC_ADD64 | |
98 | #endif /* defined(__ppc64__) */ | |
99 | ||
100 | ||
101 | /* bool OSAtomicCompareAndSwap32( int32_t oldValue, int32_t newValue, int32_t *theValue ); */ | |
102 | ||
103 | MI_ENTRY_POINT(_OSAtomicCompareAndSwap32) | |
104 | ba _COMM_PAGE_COMPARE_AND_SWAP32 | |
105 | ||
106 | ||
107 | /* bool OSAtomicCompareAndSwap64( int364_t oldValue, int64_t newValue, int64_t *theValue ); */ | |
108 | ||
109 | #if defined(__ppc64__) | |
110 | MI_ENTRY_POINT(_OSAtomicCompareAndSwap64) | |
111 | ba _COMM_PAGE_COMPARE_AND_SWAP64 | |
112 | #endif /* defined(__ppc64__) */ | |
113 | ||
114 | ||
115 | /* bool OSAtomicTestAndSet( uint32_t n, void *theAddress ); */ | |
116 | ||
117 | MI_ENTRY_POINT(_OSAtomicTestAndSet) | |
118 | mflr r12 // save return | |
119 | srwi r5,r3,3 // get byte offset of n | |
120 | rlwinm r6,r3,0,0x7 // get bit position within byte | |
121 | add r4,r4,r5 // r4 points to byte containing the bit | |
122 | lis r10,0x8000 // light bit 0 | |
123 | rlwimi r6,r4,3,0x18 // r6 is bit position within word | |
124 | clrrgi r5,r4,2 // point to word containing the bit | |
125 | srw r10,r10,r6 // get mask for bit | |
126 | addi r9,r6,1 // save bit position + 1 | |
127 | 1: | |
128 | lwz r3,0(r5) // get old word | |
129 | rlwnm r11,r3,r9,0x1 // right justify old value of bit | |
130 | or r4,r3,r10 // set it in new word | |
131 | bla _COMM_PAGE_COMPARE_AND_SWAP32 // preserves r4,r5,r9-r12 | |
132 | cmpwi r3,0 // did swap occur? | |
133 | beq-- 1b // compare-and-swap failed, try again | |
134 | mtlr r12 // restore return adddress | |
135 | mr r3,r11 // return original value of bit | |
136 | blr | |
137 | ||
138 | ||
139 | /* bool OSAtomicTestAndClear( uint32_t n, void *theAddress ); */ | |
140 | ||
141 | MI_ENTRY_POINT(_OSAtomicTestAndClear) | |
142 | mflr r12 // save return | |
143 | srwi r5,r3,3 // get byte offset of n | |
144 | rlwinm r6,r3,0,0x7 // get bit position within byte | |
145 | add r4,r4,r5 // r4 points to byte containing the bit | |
146 | lis r10,0x8000 // light bit 0 | |
147 | rlwimi r6,r4,3,0x18 // r6 is bit position within word | |
148 | clrrgi r5,r4,2 // point to word containing the bit | |
149 | srw r10,r10,r6 // get mask for bit | |
150 | addi r9,r6,1 // save bit position + 1 | |
151 | 1: | |
152 | lwz r3,0(r5) // get old word | |
153 | rlwnm r11,r3,r9,0x1 // right justify old value of bit | |
154 | andc r4,r3,r10 // clear it in new word | |
155 | bla _COMM_PAGE_COMPARE_AND_SWAP32 // preserves r4,r5,r9-r12 | |
156 | cmpwi r3,0 // did swap occur? | |
157 | beq-- 1b // compare-and-swap failed, try again | |
158 | mtlr r12 // restore return adddress | |
159 | mr r3,r11 // return original value of bit | |
160 | blr | |
3d9156a7 | 161 | |
59e0d9fe | 162 | |
3d9156a7 | 163 | /* int32_t OSAtomicAdd32Barrier( int32_t theAmount, int32_t *theValue ); */ |
59e0d9fe | 164 | |
3d9156a7 A |
165 | MI_ENTRY_POINT(_OSAtomicAdd32Barrier) |
166 | mflr r12 // save return address | |
167 | mr r5,r4 // move ptr to where compare-and-swap wants it | |
168 | mr r11,r3 // copy theAmount | |
169 | 1: | |
170 | lwz r3,0(r5) // get old value | |
171 | add r4,r3,r11 // make new value | |
172 | bla _COMM_PAGE_COMPARE_AND_SWAP32B // preserves r4,r5,r9-r12 | |
173 | cmpwi r3,0 // did swap occur? | |
174 | beq-- 1b // compare-and-swap failed, try again | |
175 | mtlr r12 // restore return adddress | |
176 | mr r3,r4 // return new value | |
177 | blr | |
178 | ||
179 | ||
180 | /* int32_t OSAtomicOr32Barrier( int32_t theMask, int32_t *theValue ); */ | |
181 | ||
182 | MI_ENTRY_POINT(_OSAtomicOr32Barrier) | |
183 | mflr r12 // save return address | |
184 | mr r5,r4 // move ptr to where compare-and-swap wants it | |
185 | mr r11,r3 // copy mask | |
186 | 1: | |
187 | lwz r3,0(r5) // get old value | |
188 | or r4,r3,r11 // make new value | |
189 | bla _COMM_PAGE_COMPARE_AND_SWAP32B // preserves r4,r5,r9-r12 | |
190 | cmpwi r3,0 // did swap occur? | |
191 | beq-- 1b // compare-and-swap failed, try again | |
192 | mtlr r12 // restore return adddress | |
193 | mr r3,r4 // return new value | |
194 | blr | |
195 | ||
196 | ||
197 | /* int32_t OSAtomicAnd32Barrier( int32_t theMask, int32_t *theValue ); */ | |
198 | ||
199 | MI_ENTRY_POINT(_OSAtomicAnd32Barrier) | |
200 | mflr r12 // save return address | |
201 | mr r5,r4 // move ptr to where compare-and-swap wants it | |
202 | mr r11,r3 // copy mask | |
203 | 1: | |
204 | lwz r3,0(r5) // get old value | |
205 | and r4,r3,r11 // make new value | |
206 | bla _COMM_PAGE_COMPARE_AND_SWAP32B // preserves r4,r5,r9-r12 | |
207 | cmpwi r3,0 // did swap occur? | |
208 | beq-- 1b // compare-and-swap failed, try again | |
209 | mtlr r12 // restore return adddress | |
210 | mr r3,r4 // return new value | |
211 | blr | |
59e0d9fe | 212 | |
59e0d9fe | 213 | |
3d9156a7 A |
214 | /* int32_t OSAtomicXor32Barrier( int32_t theMask, int32_t *theValue ); */ |
215 | ||
216 | MI_ENTRY_POINT(_OSAtomicXor32Barrier) | |
217 | mflr r12 // save return address | |
218 | mr r5,r4 // move ptr to where compare-and-swap wants it | |
219 | mr r11,r3 // copy mask | |
220 | 1: | |
221 | lwz r3,0(r5) // get old value | |
222 | xor r4,r3,r11 // make new value | |
223 | bla _COMM_PAGE_COMPARE_AND_SWAP32B // preserves r4,r5,r9-r12 | |
224 | cmpwi r3,0 // did swap occur? | |
225 | beq-- 1b // compare-and-swap failed, try again | |
226 | mtlr r12 // restore return adddress | |
227 | mr r3,r4 // return new value | |
228 | blr | |
229 | ||
230 | ||
231 | /* int64_t OSAtomicAdd64Barrier( int64_t theAmount, int64_t *theValue ); */ | |
232 | ||
233 | #if defined(__ppc64__) | |
234 | MI_ENTRY_POINT(_OSAtomicAdd64Barrier) | |
235 | mflr r12 // save return address | |
236 | mr r5,r4 // move ptr to where compare-and-swap wants it | |
237 | mr r11,r3 // copy theAmount | |
238 | 1: | |
239 | ld r3,0(r5) // get old value | |
240 | add r4,r3,r11 // make new value | |
241 | bla _COMM_PAGE_COMPARE_AND_SWAP64B // preserves r4,r5,r9-r12 | |
242 | cmpwi r3,0 // did swap occur? | |
243 | beq-- 1b // compare-and-swap failed, try again | |
244 | mtlr r12 // restore return adddress | |
245 | mr r3,r4 // return new value | |
246 | blr | |
247 | #endif /* defined(__ppc64__) */ | |
248 | ||
249 | ||
250 | /* bool OSAtomicCompareAndSwap32Barrier( int32_t oldValue, int32_t newValue, int32_t *theValue ); */ | |
251 | ||
252 | MI_ENTRY_POINT(_OSAtomicCompareAndSwap32Barrier) | |
253 | ba _COMM_PAGE_COMPARE_AND_SWAP32B | |
59e0d9fe A |
254 | |
255 | ||
3d9156a7 A |
256 | /* bool OSAtomicCompareAndSwap64Barrier( int364_t oldValue, int64_t newValue, int64_t *theValue ); */ |
257 | ||
258 | #if defined(__ppc64__) | |
259 | MI_ENTRY_POINT(_OSAtomicCompareAndSwap64Barrier) | |
260 | ba _COMM_PAGE_COMPARE_AND_SWAP64B | |
261 | #endif /* defined(__ppc64__) */ | |
262 | ||
263 | ||
264 | /* bool OSAtomicTestAndSetBarrier( uint32_t n, void *theAddress ); */ | |
265 | ||
266 | MI_ENTRY_POINT(_OSAtomicTestAndSetBarrier) | |
267 | mflr r12 // save return | |
268 | srwi r5,r3,3 // get byte offset of n | |
269 | rlwinm r6,r3,0,0x7 // get bit position within byte | |
270 | add r4,r4,r5 // r4 points to byte containing the bit | |
271 | lis r10,0x8000 // light bit 0 | |
272 | rlwimi r6,r4,3,0x18 // r6 is bit position within word | |
273 | clrrgi r5,r4,2 // point to word containing the bit | |
274 | srw r10,r10,r6 // get mask for bit | |
275 | addi r9,r6,1 // save bit position + 1 | |
276 | 1: | |
277 | lwz r3,0(r5) // get old word | |
278 | rlwnm r11,r3,r9,0x1 // right justify old value of bit | |
279 | or r4,r3,r10 // set it in new word | |
280 | bla _COMM_PAGE_COMPARE_AND_SWAP32B // preserves r4,r5,r9-r12 | |
281 | cmpwi r3,0 // did swap occur? | |
282 | beq-- 1b // compare-and-swap failed, try again | |
283 | mtlr r12 // restore return adddress | |
284 | mr r3,r11 // return original value of bit | |
285 | blr | |
286 | ||
287 | ||
288 | /* bool OSAtomicTestAndClearBarrier( uint32_t n, void *theAddress ); */ | |
289 | ||
290 | MI_ENTRY_POINT(_OSAtomicTestAndClearBarrier) | |
291 | mflr r12 // save return | |
292 | srwi r5,r3,3 // get byte offset of n | |
293 | rlwinm r6,r3,0,0x7 // get bit position within byte | |
294 | add r4,r4,r5 // r4 points to byte containing the bit | |
295 | lis r10,0x8000 // light bit 0 | |
296 | rlwimi r6,r4,3,0x18 // r6 is bit position within word | |
297 | clrrgi r5,r4,2 // point to word containing the bit | |
298 | srw r10,r10,r6 // get mask for bit | |
299 | addi r9,r6,1 // save bit position + 1 | |
300 | 1: | |
301 | lwz r3,0(r5) // get old word | |
302 | rlwnm r11,r3,r9,0x1 // right justify old value of bit | |
303 | andc r4,r3,r10 // clear it in new word | |
304 | bla _COMM_PAGE_COMPARE_AND_SWAP32B // preserves r4,r5,r9-r12 | |
305 | cmpwi r3,0 // did swap occur? | |
306 | beq-- 1b // compare-and-swap failed, try again | |
307 | mtlr r12 // restore return adddress | |
308 | mr r3,r11 // return original value of bit | |
309 | blr | |
310 | ||
59e0d9fe A |
311 | /* bool OSSpinLockTry( OSSpinLock *lock ); */ |
312 | ||
313 | MI_ENTRY_POINT(_OSSpinLockTry) | |
314 | ba _COMM_PAGE_SPINLOCK_TRY | |
315 | ||
316 | ||
317 | /* void OSSpinLockLock( OSSpinLock *lock ); */ | |
318 | ||
319 | MI_ENTRY_POINT(_OSSpinLockLock) | |
320 | ba _COMM_PAGE_SPINLOCK_LOCK | |
321 | ||
322 | ||
323 | /* void OSSpinLockUnlock( OSSpinLock *lock ); */ | |
324 | ||
325 | MI_ENTRY_POINT(_OSSpinLockUnlock) | |
326 | ba _COMM_PAGE_SPINLOCK_UNLOCK | |
327 | ||
328 | ||
329 | /* void OSMemoryBarrier( void ); */ | |
330 | ||
331 | MI_ENTRY_POINT(_OSMemoryBarrier) | |
332 | ba _COMM_PAGE_MEMORY_BARRIER | |
333 |