]> git.saurik.com Git - apple/libc.git/blame - ppc/sys/OSAtomic.s
Libc-391.5.22.tar.gz
[apple/libc.git] / ppc / sys / OSAtomic.s
CommitLineData
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
38MI_ENTRY_POINT(_OSAtomicAdd32)
39 ba _COMM_PAGE_ATOMIC_ADD32
40
41
42/* int32_t OSAtomicOr32( int32_t theMask, int32_t *theValue ); */
43
44MI_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
481:
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
61MI_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
651:
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
78MI_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
821:
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__)
96MI_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
103MI_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__)
110MI_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
117MI_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
1271:
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
141MI_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
1511:
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
165MI_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
1691:
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
182MI_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
1861:
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
199MI_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
2031:
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
216MI_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
2201:
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__)
234MI_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
2381:
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
252MI_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__)
259MI_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
266MI_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
2761:
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
290MI_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
3001:
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
313MI_ENTRY_POINT(_OSSpinLockTry)
314 ba _COMM_PAGE_SPINLOCK_TRY
315
316
317/* void OSSpinLockLock( OSSpinLock *lock ); */
318
319MI_ENTRY_POINT(_OSSpinLockLock)
320 ba _COMM_PAGE_SPINLOCK_LOCK
321
322
323/* void OSSpinLockUnlock( OSSpinLock *lock ); */
324
325MI_ENTRY_POINT(_OSSpinLockUnlock)
326 ba _COMM_PAGE_SPINLOCK_UNLOCK
327
328
329/* void OSMemoryBarrier( void ); */
330
331MI_ENTRY_POINT(_OSMemoryBarrier)
332 ba _COMM_PAGE_MEMORY_BARRIER
333