blob: f639232951f1bc19ad8c4f7eb28cfe55d63a888a [file] [log] [blame]
////////////////////////////////////////////////////////////////////////////
//
// ia64/atomic.s
//
// $Id$
//
////////////////////////////////////////////////////////////////////////////
//
// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements. See the NOTICE file distributed
// with this work for additional information regarding copyright
// ownership. The ASF licenses this file to you 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.
//
// Copyright 2003-2006 Rogue Wave Software.
//
////////////////////////////////////////////////////////////////////////////
.text
//.pred.safe_across_calls p1-p5,p16-p63
.psr abi32
.psr msb
////////////////////////////////////////////////////////////////////////////
// extern "C" char __rw_atomic_xchg8 (char *x, char y);
//
// Atomically assigns the 8-bit value y to *x and returns
// the original (before assignment) 8-bit value of *x.
////////////////////////////////////////////////////////////////////////////
.global __rw_atomic_xchg8#
.proc __rw_atomic_xchg8#
__rw_atomic_xchg8:
.prologue
.body
// .mfb
addp4 r9 = 0, r32 // Needed to be able to dereference a 32 bit pointer
;;
xchg1 r8 = [r9], r33
nop 0
br.ret.sptk.many b0
.endp __rw_atomic_xchg8#
////////////////////////////////////////////////////////////////////////////
// extern "C" char __rw_atomic_add8 (char *x, int y);
//
// Atomically increments the 8-bit value *x by y and returns
// the new (after increment) 8-bit value of *x.
////////////////////////////////////////////////////////////////////////////
.global __rw_atomic_add8#
.proc __rw_atomic_add8#
__rw_atomic_add8:
.prologue
.body
// .mmb
mf
addp4 r9 = 0, r32 // Needed to be able to dereference a 32 bit pointer
;;
ld1.acq r15 = [r9]
nop 0
;;
.add8_busywait:
// .mmi
mov ar.ccv = r15
add r8 = r15, r33
mov r2 = r15
;;
// .mmb
nop 0
cmpxchg1.acq r15 = [r9], r8, ar.ccv
nop 0
;;
// .mbb
cmp.ne p8, p9 = r2, r15
(p9) br.ret.dpnt.many rp
br .add8_busywait
.endp __rw_atomic_add8#
////////////////////////////////////////////////////////////////////////////
// extern "C" short __rw_atomic_xchg16 (short *x, short y);
//
// Atomically assigns the 16-bit value y to *x and returns
// the original (before assignment) 16-bit value of *x.
////////////////////////////////////////////////////////////////////////////
.global __rw_atomic_xchg16#
.proc __rw_atomic_xchg16#
__rw_atomic_xchg16:
.prologue
.body
// .mfb
addp4 r9 = 0, r32 // Needed to be able to dereference a 32 bit pointer
;;
xchg2 r8 = [r9], r33
nop 0
br.ret.sptk.many b0
.endp __rw_atomic_xchg16#
////////////////////////////////////////////////////////////////////////////
// extern "C" short __rw_atomic_add16 (short *x, short y);
//
// Atomically increments the 16-bit value *x by y and returns
// the new (after increment) 16-bit value of *x.
////////////////////////////////////////////////////////////////////////////
.global __rw_atomic_add16#
.proc __rw_atomic_add16#
__rw_atomic_add16:
.prologue
.body
// .mmb
mf
addp4 r9 = 0, r32 // Needed to be able to dereference a 32 bit pointer
;;
ld2.acq r15 = [r9]
nop 0
;;
.add16_busywait:
// .mmi
mov ar.ccv = r15
add r8 = r15, r33
mov r2 = r15
;;
// .mmb
nop 0
cmpxchg2.acq r15 = [r9], r8, ar.ccv
nop 0
;;
// .mbb
cmp.ne p8, p9 = r2, r15
(p9) br.ret.dpnt.many rp
br .add16_busywait
.endp __rw_atomic_add16#
////////////////////////////////////////////////////////////////////////////
// extern "C" int __rw_atomic_xchg32 (int *x, int y);
//
// Atomically assigns the 32-bit value y to *x and returns
// the original (before assignment) 32-bit value of *x.
////////////////////////////////////////////////////////////////////////////
.global __rw_atomic_xchg32#
.proc __rw_atomic_xchg32#
__rw_atomic_xchg32:
.prologue
.body
// .mfb
addp4 r9 = 0, r32 // Needed to be able to dereference a 32 bit pointer
;;
xchg4 r8 = [r9], r33
nop 0
br.ret.sptk.many b0
.endp __rw_atomic_xchg32#
////////////////////////////////////////////////////////////////////////////
// extern "C" int __rw_atomic_add32 (int *x, int y);
//
// Atomically increments the 32-bit value *x by y and returns
// the new (after increment) 32-bit value of *x.
////////////////////////////////////////////////////////////////////////////
.global __rw_atomic_add32#
.proc __rw_atomic_add32#
__rw_atomic_add32:
.prologue
.body
// .mmb
mf
addp4 r9 = 0, r32 // Needed to be able to dereference a 32 bit pointer
;;
ld4.acq r15 = [r9]
nop 0
;;
.add32_busywait:
// .mmi
mov ar.ccv = r15
add r8 = r15, r33
mov r2 = r15
;;
// .mmb
nop 0
cmpxchg4.acq r15 = [r9], r8, ar.ccv
nop 0
;;
// .mbb
cmp4.ne p8, p9 = r2, r15
(p9) br.ret.dpnt.many rp
br .add32_busywait
.endp __rw_atomic_add32#
////////////////////////////////////////////////////////////////////////////
// extern "C" int64_t __rw_atomic_xchg64 (int64_t *x, int64_t y);
//
// Atomically assigns the 64-bit value y to *x and returns
// the original (before assignment) 64-bit value of *x.
////////////////////////////////////////////////////////////////////////////
.global __rw_atomic_xchg64#
.proc __rw_atomic_xchg64#
__rw_atomic_xchg64:
.prologue
.body
// .mfb
addp4 r9 = 0, r32 // Needed to be able to dereference a 32 bit pointer
;;
xchg8 r8 = [r9], r33
nop 0
br.ret.sptk.many b0
.endp __rw_atomic_xchg64#
////////////////////////////////////////////////////////////////////////////
// extern "C" int64_t __rw_atomic_add64 (int64_t *x, int64_t y);
//
// Atomically increments the 16-bit value *x by y and returns
// the new (after increment) 16-bit value of *x.
////////////////////////////////////////////////////////////////////////////
.global __rw_atomic_add64#
.proc __rw_atomic_add64#
__rw_atomic_add64:
.prologue
.body
// .mmb
mf
addp4 r9 = 0, r32 // Needed to be able to dereference a 32 bit pointer
;;
ld8.acq r15 = [r9]
nop 0
;;
.add64_busywait:
// .mmi
mov ar.ccv = r15
add r8 = r15, r33
mov r2 = r15
;;
// .mmb
nop 0
cmpxchg8.acq r15 = [r9], r8, ar.ccv
nop 0
;;
// .mbb
cmp.ne p8, p9 = r2, r15
(p9) br.ret.dpnt.many rp
br .add64_busywait
.endp __rw_atomic_add64#