]> git.saurik.com Git - apple/libc.git/blob - ppc/sys/OSAtomic.s
Libc-391.5.22.tar.gz
[apple/libc.git] / ppc / sys / OSAtomic.s
1 /*
2 * Copyright (c) 2004 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 #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
161
162
163 /* int32_t OSAtomicAdd32Barrier( int32_t theAmount, int32_t *theValue ); */
164
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
212
213
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
254
255
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
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