| //////////////////////////////////////////////////////////////////////////// |
| // |
| // 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# |