]> git.saurik.com Git - apple/libc.git/blobdiff - ppc/sys/OSAtomic.s
Libc-763.11.tar.gz
[apple/libc.git] / ppc / sys / OSAtomic.s
index d2680852340375b873201526b65b18b2f0c67993..24858e901e314c389dfaa153470ef83c30da571b 100644 (file)
@@ -1,10 +1,9 @@
 /*
- * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2007 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2006 Apple Computer, Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
- * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
- * 
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
@@ -92,6 +91,60 @@ MI_ENTRY_POINT(_OSAtomicXor32)
     blr
 
 
+/* int32_t     OSAtomicOr32Orig( int32_t theMask, int32_t *theValue ); */
+
+MI_ENTRY_POINT(_OSAtomicOr32Orig)
+    mflr    r12                 // save return address
+    mr      r5,r4               // move ptr to where compare-and-swap wants it
+    mr      r11,r3              // copy mask
+1:
+    lwz     r3,0(r5)            // get old value
+    mr      r10,r3             // save old value
+    or      r4,r3,r11           // make new value
+    bla     _COMM_PAGE_COMPARE_AND_SWAP32   // preserves r4,r5,r9-r12
+    cmpwi   r3,0                // did swap occur?
+    beq--   1b                  // compare-and-swap failed, try again
+    mtlr    r12                 // restore return adddress
+    mr      r3,r10              // return old value
+    blr
+
+
+/* int32_t     OSAtomicAnd32Orig( int32_t theMask, int32_t *theValue ); */
+
+MI_ENTRY_POINT(_OSAtomicAnd32Orig)
+    mflr    r12                 // save return address
+    mr      r5,r4               // move ptr to where compare-and-swap wants it
+    mr      r11,r3              // copy mask
+1:
+    lwz     r3,0(r5)            // get old value
+    mr      r10,r3             // save old value
+    and     r4,r3,r11           // make new value
+    bla     _COMM_PAGE_COMPARE_AND_SWAP32   // preserves r4,r5,r9-r12
+    cmpwi   r3,0                // did swap occur?
+    beq--   1b                  // compare-and-swap failed, try again
+    mtlr    r12                 // restore return adddress
+    mr      r3,r10              // return old value
+    blr
+
+
+/* int32_t     OSAtomicXor32Orig( int32_t theMask, int32_t *theValue ); */
+
+MI_ENTRY_POINT(_OSAtomicXor32Orig)
+    mflr    r12                 // save return address
+    mr      r5,r4               // move ptr to where compare-and-swap wants it
+    mr      r11,r3              // copy mask
+1:
+    lwz     r3,0(r5)            // get old value
+    mr      r10,r3             // save old value
+    xor     r4,r3,r11           // make new value
+    bla     _COMM_PAGE_COMPARE_AND_SWAP32   // preserves r4,r5,r9-r12
+    cmpwi   r3,0                // did swap occur?
+    beq--   1b                  // compare-and-swap failed, try again
+    mtlr    r12                 // restore return adddress
+    mr      r3,r10              // return old value
+    blr
+
+
 /* int64_t     OSAtomicAdd64( int64_t theAmount, int64_t *theValue ); */
 
 #if defined(__ppc64__)
@@ -101,16 +154,28 @@ MI_ENTRY_POINT(_OSAtomicAdd64)
 
 
 /* bool OSAtomicCompareAndSwap32( int32_t oldValue, int32_t newValue, int32_t *theValue ); */
+/* bool OSAtomicCompareAndSwap64( int64_t oldValue, int64_t newValue, int64_t *theValue ); */
+/* bool OSAtomicCompareAndSwapPtr( void* oldValue, void* newValue, void* *theValue ); */
+/* bool OSAtomicCompareAndSwapInt( int oldValue, int newValue, int *theValue ); */
+/* bool OSAtomicCompareAndSwapLong( long oldValue, long newValue, long *theValue ); */
 
 MI_ENTRY_POINT(_OSAtomicCompareAndSwap32)
     ba      _COMM_PAGE_COMPARE_AND_SWAP32
-    
-
-/* bool OSAtomicCompareAndSwap64( int364_t oldValue, int64_t newValue, int64_t *theValue ); */
+MI_ENTRY_POINT(_OSAtomicCompareAndSwapInt)
+    ba      _COMM_PAGE_COMPARE_AND_SWAP32
 
 #if defined(__ppc64__)
 MI_ENTRY_POINT(_OSAtomicCompareAndSwap64)
     ba      _COMM_PAGE_COMPARE_AND_SWAP64
+MI_ENTRY_POINT(_OSAtomicCompareAndSwapPtr)
+    ba      _COMM_PAGE_COMPARE_AND_SWAP64
+MI_ENTRY_POINT(_OSAtomicCompareAndSwapLong)
+    ba      _COMM_PAGE_COMPARE_AND_SWAP64
+#else  /* !defined(__ppc64__) */
+MI_ENTRY_POINT(_OSAtomicCompareAndSwapPtr)
+    ba      _COMM_PAGE_COMPARE_AND_SWAP32
+MI_ENTRY_POINT(_OSAtomicCompareAndSwapLong)
+    ba      _COMM_PAGE_COMPARE_AND_SWAP32
 #endif  /* defined(__ppc64__) */
 
 
@@ -160,35 +225,247 @@ MI_ENTRY_POINT(_OSAtomicTestAndClear)
     mtlr    r12                 // restore return adddress
     mr      r3,r11              // return original value of bit
     blr
-    
 
-/* void *      OSAtomicDequeue( void ** inList, size_t inOffset); */
+/* int32_t     OSAtomicAdd32Barrier( int32_t theAmount, int32_t *theValue ); */
 
-MI_ENTRY_POINT(_OSAtomicDequeue)
-    ba      _COMM_PAGE_DEQUEUE
-    
+MI_ENTRY_POINT(_OSAtomicAdd32Barrier)
+    mflr    r12                 // save return address
+    mr      r5,r4               // move ptr to where compare-and-swap wants it
+    mr      r11,r3              // copy theAmount
+1:
+    lwz     r3,0(r5)            // get old value
+    add     r4,r3,r11           // make new value
+    bla     _COMM_PAGE_COMPARE_AND_SWAP32B   // preserves r4,r5,r9-r12
+    cmpwi   r3,0                // did swap occur?
+    beq--   1b                  // compare-and-swap failed, try again
+    mtlr    r12                 // restore return adddress
+    mr      r3,r4               // return new value
+    blr
 
-/* void OSAtomicEnqueue( void ** inList, void * inNewLink, size_t inOffset); */
 
-MI_ENTRY_POINT(_OSAtomicEnqueue)
-    ba      _COMM_PAGE_ENQUEUE
-    
+/* int32_t     OSAtomicOr32Barrier( int32_t theMask, int32_t *theValue ); */
+
+MI_ENTRY_POINT(_OSAtomicOr32Barrier)
+    mflr    r12                 // save return address
+    mr      r5,r4               // move ptr to where compare-and-swap wants it
+    mr      r11,r3              // copy mask
+1:
+    lwz     r3,0(r5)            // get old value
+    or      r4,r3,r11           // make new value
+    bla     _COMM_PAGE_COMPARE_AND_SWAP32B   // preserves r4,r5,r9-r12
+    cmpwi   r3,0                // did swap occur?
+    beq--   1b                  // compare-and-swap failed, try again
+    mtlr    r12                 // restore return adddress
+    mr      r3,r4               // return new value
+    blr
+
+
+/* int32_t     OSAtomicAnd32Barrier( int32_t theMask, int32_t *theValue ); */
+
+MI_ENTRY_POINT(_OSAtomicAnd32Barrier)
+    mflr    r12                 // save return address
+    mr      r5,r4               // move ptr to where compare-and-swap wants it
+    mr      r11,r3              // copy mask
+1:
+    lwz     r3,0(r5)            // get old value
+    and     r4,r3,r11           // make new value
+    bla     _COMM_PAGE_COMPARE_AND_SWAP32B   // preserves r4,r5,r9-r12
+    cmpwi   r3,0                // did swap occur?
+    beq--   1b                  // compare-and-swap failed, try again
+    mtlr    r12                 // restore return adddress
+    mr      r3,r4               // return new value
+    blr
+
+
+/* int32_t     OSAtomicXor32Barrier( int32_t theMask, int32_t *theValue ); */
+
+MI_ENTRY_POINT(_OSAtomicXor32Barrier)
+    mflr    r12                 // save return address
+    mr      r5,r4               // move ptr to where compare-and-swap wants it
+    mr      r11,r3              // copy mask
+1:
+    lwz     r3,0(r5)            // get old value
+    xor     r4,r3,r11           // make new value
+    bla     _COMM_PAGE_COMPARE_AND_SWAP32B   // preserves r4,r5,r9-r12
+    cmpwi   r3,0                // did swap occur?
+    beq--   1b                  // compare-and-swap failed, try again
+    mtlr    r12                 // restore return adddress
+    mr      r3,r4               // return new value
+    blr
+
 
+/* int32_t     OSAtomicOr32OrigBarrier( int32_t theMask, int32_t *theValue ); */
+
+MI_ENTRY_POINT(_OSAtomicOr32OrigBarrier)
+    mflr    r12                 // save return address
+    mr      r5,r4               // move ptr to where compare-and-swap wants it
+    mr      r11,r3              // copy mask
+1:
+    lwz     r3,0(r5)            // get old value
+    mr      r10,r3             // save old value
+    or      r4,r3,r11           // make new value
+    bla     _COMM_PAGE_COMPARE_AND_SWAP32B   // preserves r4,r5,r9-r12
+    cmpwi   r3,0                // did swap occur?
+    beq--   1b                  // compare-and-swap failed, try again
+    mtlr    r12                 // restore return adddress
+    mr      r3,r10             // return old value
+    blr
+
+
+/* int32_t     OSAtomicAnd32OrigBarrier( int32_t theMask, int32_t *theValue ); */
+
+MI_ENTRY_POINT(_OSAtomicAnd32OrigBarrier)
+    mflr    r12                 // save return address
+    mr      r5,r4               // move ptr to where compare-and-swap wants it
+    mr      r11,r3              // copy mask
+1:
+    lwz     r3,0(r5)            // get old value
+    mr      r10,r3             // save old value
+    and     r4,r3,r11           // make new value
+    bla     _COMM_PAGE_COMPARE_AND_SWAP32B   // preserves r4,r5,r9-r12
+    cmpwi   r3,0                // did swap occur?
+    beq--   1b                  // compare-and-swap failed, try again
+    mtlr    r12                 // restore return adddress
+    mr      r3,r10             // return old value
+    blr
+
+
+/* int32_t     OSAtomicXor32OrigBarrier( int32_t theMask, int32_t *theValue ); */
+
+MI_ENTRY_POINT(_OSAtomicXor32OrigBarrier)
+    mflr    r12                 // save return address
+    mr      r5,r4               // move ptr to where compare-and-swap wants it
+    mr      r11,r3              // copy mask
+1:
+    lwz     r3,0(r5)            // get old value
+    mr      r10,r3             // save old value
+    xor     r4,r3,r11           // make new value
+    bla     _COMM_PAGE_COMPARE_AND_SWAP32B   // preserves r4,r5,r9-r12
+    cmpwi   r3,0                // did swap occur?
+    beq--   1b                  // compare-and-swap failed, try again
+    mtlr    r12                 // restore return adddress
+    mr      r3,r10             // return old value
+    blr
+
+
+/* int64_t     OSAtomicAdd64Barrier( int64_t theAmount, int64_t *theValue ); */
+
+#if defined(__ppc64__)
+MI_ENTRY_POINT(_OSAtomicAdd64Barrier)
+    mflr    r12                 // save return address
+    mr      r5,r4               // move ptr to where compare-and-swap wants it
+    mr      r11,r3              // copy theAmount
+1:
+    ld      r3,0(r5)            // get old value
+    add     r4,r3,r11           // make new value
+    bla     _COMM_PAGE_COMPARE_AND_SWAP64B   // preserves r4,r5,r9-r12
+    cmpwi   r3,0                // did swap occur?
+    beq--   1b                  // compare-and-swap failed, try again
+    mtlr    r12                 // restore return adddress
+    mr      r3,r4               // return new value
+    blr
+#endif  /* defined(__ppc64__) */
+
+
+/* bool OSAtomicCompareAndSwap32Barrier( int32_t oldValue, int32_t newValue, int32_t *theValue ); */
+/* bool OSAtomicCompareAndSwap64Barrier( int64_t oldValue, int64_t newValue, int64_t *theValue ); */
+/* bool OSAtomicCompareAndSwapPtrBarrier( void* oldValue, void* newValue, void* *theValue ); */
+/* bool OSAtomicCompareAndSwapIntBarrier( int oldValue, int newValue, int *theValue ); */
+/* bool OSAtomicCompareAndSwapLongBarrier( long oldValue, long newValue, long *theValue ); */
+
+MI_ENTRY_POINT(_OSAtomicCompareAndSwap32Barrier)
+    ba      _COMM_PAGE_COMPARE_AND_SWAP32B
+MI_ENTRY_POINT(_OSAtomicCompareAndSwapIntBarrier)
+    ba      _COMM_PAGE_COMPARE_AND_SWAP32B
+
+#if defined(__ppc64__)
+MI_ENTRY_POINT(_OSAtomicCompareAndSwap64Barrier)
+    ba      _COMM_PAGE_COMPARE_AND_SWAP64B
+MI_ENTRY_POINT(_OSAtomicCompareAndSwapPtrBarrier)
+    ba      _COMM_PAGE_COMPARE_AND_SWAP64B
+MI_ENTRY_POINT(_OSAtomicCompareAndSwapLongBarrier)
+    ba      _COMM_PAGE_COMPARE_AND_SWAP64B
+#else  /* !defined(__ppc64__) */
+MI_ENTRY_POINT(_OSAtomicCompareAndSwapPtrBarrier)
+    ba      _COMM_PAGE_COMPARE_AND_SWAP32B
+MI_ENTRY_POINT(_OSAtomicCompareAndSwapLongBarrier)
+    ba      _COMM_PAGE_COMPARE_AND_SWAP32B
+#endif  /* defined(__ppc64__) */
+
+
+/* bool OSAtomicTestAndSetBarrier( uint32_t n, void *theAddress ); */
+
+MI_ENTRY_POINT(_OSAtomicTestAndSetBarrier)
+    mflr    r12                 // save return
+    srwi    r5,r3,3             // get byte offset of n
+    rlwinm  r6,r3,0,0x7         // get bit position within byte
+    add     r4,r4,r5            // r4 points to byte containing the bit
+    lis     r10,0x8000          // light bit 0
+    rlwimi  r6,r4,3,0x18        // r6 is bit position within word
+    clrrgi  r5,r4,2             // point to word containing the bit
+    srw     r10,r10,r6          // get mask for bit
+    addi    r9,r6,1             // save bit position + 1
+1:
+    lwz     r3,0(r5)            // get old word
+    rlwnm   r11,r3,r9,0x1       // right justify old value of bit
+    or      r4,r3,r10           // set it in new word
+    bla     _COMM_PAGE_COMPARE_AND_SWAP32B   // preserves r4,r5,r9-r12
+    cmpwi   r3,0                // did swap occur?
+    beq--   1b                  // compare-and-swap failed, try again
+    mtlr    r12                 // restore return adddress
+    mr      r3,r11              // return original value of bit
+    blr
+
+
+/* bool OSAtomicTestAndClearBarrier( uint32_t n, void *theAddress ); */
+
+MI_ENTRY_POINT(_OSAtomicTestAndClearBarrier)
+    mflr    r12                 // save return
+    srwi    r5,r3,3             // get byte offset of n
+    rlwinm  r6,r3,0,0x7         // get bit position within byte
+    add     r4,r4,r5            // r4 points to byte containing the bit
+    lis     r10,0x8000          // light bit 0
+    rlwimi  r6,r4,3,0x18        // r6 is bit position within word
+    clrrgi  r5,r4,2             // point to word containing the bit
+    srw     r10,r10,r6          // get mask for bit
+    addi    r9,r6,1             // save bit position + 1
+1:
+    lwz     r3,0(r5)            // get old word
+    rlwnm   r11,r3,r9,0x1       // right justify old value of bit
+    andc    r4,r3,r10           // clear it in new word
+    bla     _COMM_PAGE_COMPARE_AND_SWAP32B   // preserves r4,r5,r9-r12
+    cmpwi   r3,0                // did swap occur?
+    beq--   1b                  // compare-and-swap failed, try again
+    mtlr    r12                 // restore return adddress
+    mr      r3,r11              // return original value of bit
+    blr
+    
 /* bool    OSSpinLockTry( OSSpinLock *lock ); */
 
 MI_ENTRY_POINT(_OSSpinLockTry)
+    .globl  __spin_lock_try
+__spin_lock_try:
     ba      _COMM_PAGE_SPINLOCK_TRY
     
 
 /* void    OSSpinLockLock( OSSpinLock *lock ); */
 
 MI_ENTRY_POINT(_OSSpinLockLock)
+    .globl  _spin_lock
+    .globl  __spin_lock
+_spin_lock:
+__spin_lock:
     ba      _COMM_PAGE_SPINLOCK_LOCK
     
 
 /* void    OSSpinLockUnlock( OSSpinLock *lock ); */
 
 MI_ENTRY_POINT(_OSSpinLockUnlock)
+    .globl  _spin_unlock
+    .globl  __spin_unlock
+_spin_unlock:
+__spin_unlock:
     ba      _COMM_PAGE_SPINLOCK_UNLOCK
     
 
@@ -197,3 +474,14 @@ MI_ENTRY_POINT(_OSSpinLockUnlock)
 MI_ENTRY_POINT(_OSMemoryBarrier)
     ba     _COMM_PAGE_MEMORY_BARRIER
 
+
+/* void  OSAtomicEnqueue( OSQueueHead *list, void *new, size_t offset); */
+
+MI_ENTRY_POINT(_OSAtomicEnqueue)
+    ba      _COMM_PAGE_ENQUEUE
+    
+    
+/* void* OSAtomicDequeue( OSQueueHead *list, size_t offset); */
+
+MI_ENTRY_POINT(_OSAtomicDequeue)
+    ba      _COMM_PAGE_DEQUEUE