/* * ========== Copyright Header Begin ========================================== * * OpenSPARC T2 Processor File: BL_Atomic.s * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES. * * The above named program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License version 2 as published by the Free Software Foundation. * * The above named program is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this work; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * ========== Copyright Header End ============================================ */ #if defined(ARCH_X64) .text /*============================================================================*\ * int64_t bl_atomic_add64( int64_t* var, int64_t val ) * * Implement atomic 64bit add with casxa, The value returned is the old *var \*============================================================================*/ .align 16 .globl bl_atomic_add64 .type bl_atomic_add64, @function bl_atomic_add64: movq %rsi,%rax lock xaddq %rax,(%rdi) ret .size bl_atomic_add64, [.-bl_atomic_add64] /*============================================================================*\ * int32_t bl_atomic_add32( int32_t* var, int32_t val ) * * Implement atomic 32bit add with casa. The value returned in the old *var \*============================================================================*/ .align 16 .globl bl_atomic_add32 .type bl_atomic_add32, @function bl_atomic_add32: movl %esi,%eax lock xaddl %eax,(%rdi) ret .size bl_atomic_add32, [.-bl_atomic_add32] #else .section ".text" /*============================================================================*\ * int64_t bl_atomic_add64( int64_t* var, int64_t val ) * * Implement atomic 64bit add with casxa, The value returned is the old *var \*============================================================================*/ .global bl_atomic_add64 .type bl_atomic_add64, #function bl_atomic_add64: ldx [%o0],%o2 /* Load *var */ 1: add %o2,%o1,%o3 /* Goal is *var + val */ casxa [%o0]0x80,%o2,%o3 /* */ cmp %o2,%o3 /* Test if we added to same *var value */ bne %xcc,1b /* If not we did not */ mov %o3,%o2 /* Try again with new *var (casxa is ldx) */ retl mov %o3,%o0 /* Return previous value */ /*============================================================================*\ * int32_t bl_atomic_add32( int32_t* var, int32_t val ) * * Implement atomic 32bit add with casa. The value returned in the old *var \*============================================================================*/ .global bl_atomic_add32 .type bl_atomic_add32, #function bl_atomic_add32: ld [%o0],%o2 /* Load *var */ 1: add %o2,%o1,%o3 /* Goal is *var = val + *var */ casa [%o0]0x80,%o2,%o3 /* */ cmp %o2,%o3 /* Test if we added to same *var value */ bne %icc,1b /* If not we did not */ mov %o3,%o2 /* Try again with new *var (casxa is ldx) */ retl sra %o3,0,%o0 /* Return previous value (32 bit) */ #endif