blob: f53251a77b14d1b631493bdf6ca402b661c7fc9b [file] [log] [blame]
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! atomic-sparc.s
!
! $Id$
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! Copyright 2005-2006 The Apache Software Foundation or its licensors,
! as applicable.
!
! Copyright 2002-2006 Rogue Wave Software.
!
! Licensed under the Apache License, Version 2.0 (the "License");
! you may not use this file except in compliance with the License.
! You may obtain a copy of the License at
!
! http://www.apache.org/licenses/LICENSE-2.0
!
! Unless required by applicable law or agreed to in writing, software
! distributed under the License is distributed on an "AS IS" BASIS,
! WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
! See the License for the specific language governing permissions and
! limitations under the License.
!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.section ".text"
.align 8
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! extern "C" int __rw_atomic_xchg32 (int *x, int y);
!
! Atomically assigns the 32-bit value value y to *x and returns
! the original (before assignment) 32-bit value of *x.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.type __rw_atomic_xchg32, #function
.global __rw_atomic_xchg32
__rw_atomic_xchg32: ! (int *x: %o0, int y: %o1)
swap [%o0], %o1 ! *x <-> y
retl
mov %o1, %o0 ! return original value of *x
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! extern "C" int __rw_atomic_add32 (int *x, int y);
!
! Atomically increments the 32-bit value value *x by y and returns
! the new (after increment) 32-bit value of *x.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.type __rw_atomic_add32, #function
.global __rw_atomic_add32
__rw_atomic_add32: ! (int *x: %o0, int y: %o1)
mov -1, %o2 ! INT_MAX is reserved
srl %o2, 1, %o2 ! %o2 = -1U >> 1 (== INT_MAX)
.__rw_retry:
mov %o2, %o3 ! make a copy for swap
swap [%o0], %o3 ! swap *x for %o3
cmp %o3, %o2 ! if *x == INT_MAX (i.e., resource is locked)
beq,a .__rw_busywait ! then busy-wait (else annul next insn)
nop ! else perform add and return
add %o3, %o1, %o2 ! %o2 = *x + y
st %o2, [%o0] ! store the sum in *x
retl ! return to caller
mov %o2, %o0 ! (delayed) store result in %o0
.__rw_busywait: ! busy-wait with loads (cheaper than swaps)
cmp %o3, %o2 ! if %o3 == INT_MAX
be .__rw_busywait ! then spin
ld [%o0], %o3 ! (delayed) %o3 = *x
ba,a .__rw_retry ! otherwise, try again for lock
nop