diff --git a/opal/config/opal_config_asm.m4 b/opal/config/opal_config_asm.m4 index b1c11aea0d..f102488d1f 100644 --- a/opal/config/opal_config_asm.m4 +++ b/opal/config/opal_config_asm.m4 @@ -10,6 +10,7 @@ dnl University of Stuttgart. All rights reserved. dnl Copyright (c) 2004-2005 The Regents of the University of California. dnl All rights reserved. dnl Copyright (c) 2008-2009 Cisco Systems, Inc. All rights reserved. +dnl Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved. dnl $COPYRIGHT$ dnl dnl Additional copyrights may follow @@ -562,6 +563,13 @@ dnl For PowerPC, this would be: dnl dnl "li %0,0" : "=&r"(ret) dnl +dnl For testing ia32 assembly, the assembly instruction xaddl is +dnl tested. The xaddl instruction is used by some of the atomic +dnl implementations so it makes sense to test for it. In addition, +dnl some compilers (i.e. earlier versions of Sun Studio 12) do not +dnl necessarily handle xaddl properly, so that needs to be detected +dnl during configure time. +dnl dnl DEFINE OMPI_GCC_INLINE_ASSEMBLY to 0 or 1 depending on GCC dnl support dnl @@ -588,6 +596,7 @@ AC_DEFUN([OMPI_CHECK_INLINE_C_GCC],[ AC_RUN_IFELSE([AC_LANG_PROGRAM([ AC_INCLUDES_DEFAULT], [[int ret = 1; +int negone = -1; __asm__ __volatile__ ($assembly); return ret;]])], [asm_result="yes"], [asm_result="no"], @@ -603,6 +612,7 @@ return ret;]])], AC_LINK_IFELSE([AC_LANG_PROGRAM([ AC_INCLUDES_DEFAULT], [[int ret = 1; +int negone = -1; __asm__ __volatile__ ($assembly); return ret;]])], [asm_result="yes"], [asm_result="no"]) @@ -642,6 +652,7 @@ AC_DEFUN([OMPI_CHECK_INLINE_CXX_GCC],[ AC_RUN_IFELSE([AC_LANG_PROGRAM([ AC_INCLUDES_DEFAULT], [[int ret = 1; +int negone = -1; __asm__ __volatile__ ($assembly); return ret;]])], [asm_result="yes"], [asm_result="no"], @@ -656,6 +667,7 @@ return ret;]])], AC_LINK_IFELSE([AC_LANG_PROGRAM([ AC_INCLUDES_DEFAULT], [[int ret = 1; +int negone = -1; __asm__ __volatile__ ($assembly); return ret;]])], [asm_result="yes"], [asm_result="no"]) @@ -873,7 +885,7 @@ AC_DEFUN([OPAL_CONFIG_ASM],[ ompi_cv_asm_arch="AMD64" fi OPAL_ASM_SUPPORT_64BIT=1 - OMPI_GCC_INLINE_ASSIGN='"movl [$]0, %0" : "=&r"(ret)' + OMPI_GCC_INLINE_ASSIGN='"xaddl %1,%0" : "=m"(ret), "+r"(negone)' ;; ia64-*) diff --git a/opal/include/opal/sys/ia32/atomic.h b/opal/include/opal/sys/ia32/atomic.h index 91f8fefb62..6fdd47e130 100644 --- a/opal/include/opal/sys/ia32/atomic.h +++ b/opal/include/opal/sys/ia32/atomic.h @@ -9,7 +9,7 @@ * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. - * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserverd. + * Copyright (c) 2007-2010 Oracle and/or its affiliates. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow @@ -164,11 +164,12 @@ static inline int opal_atomic_cmpset_64(volatile int64_t *addr, */ static inline int32_t opal_atomic_add_32(volatile int32_t* v, int i) { + int ret = i; __asm__ __volatile__( - SMPLOCK "addl %1,%0" - :"=m" (*v) - :"ir" (i), "m" (*v)); - return (*v); /* should be an atomic operation */ + SMPLOCK "xaddl %1,%0" + :"=m" (*v), "+r" (ret) + ); + return (ret+i); } @@ -181,11 +182,12 @@ static inline int32_t opal_atomic_add_32(volatile int32_t* v, int i) */ static inline int32_t opal_atomic_sub_32(volatile int32_t* v, int i) { + int ret = -i; __asm__ __volatile__( - SMPLOCK "subl %1,%0" - :"=m" (*v) - :"ir" (i), "m" (*v)); - return (*v); /* should be an atomic operation */ + SMPLOCK "xaddl %1,%0" + :"=m" (*v), "+r" (ret) + ); + return (ret-i); } #endif /* OMPI_GCC_INLINE_ASSEMBLY */