Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 17 additions & 23 deletions config/opal_config_asm.m4
Original file line number Diff line number Diff line change
Expand Up @@ -738,34 +738,28 @@ AC_DEFUN([OPAL_CHECK_INLINE_C_GCC],[

AC_MSG_CHECKING([if $CC supports GCC inline assembly])

if test "$opal_cv_c_compiler_vendor" = "portland group" ; then
# PGI seems to have some issues with our inline assembly.
# Disable for now.
asm_result="no (Portland Group)"
else
if test ! "$assembly" = "" ; then
AC_RUN_IFELSE([AC_LANG_PROGRAM([
AC_INCLUDES_DEFAULT],
[[int ret = 1;
if test ! "$assembly" = "" ; then
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"],
[asm_result="unknown"])
else
assembly="test skipped - assuming no"
fi
return ret;
]])],
[asm_result="yes"], [asm_result="no"],
[asm_result="unknown"])
else
assembly="test skipped - assuming no"
fi

# if we're cross compiling, just try to compile and figure good enough
if test "$asm_result" = "unknown" ; then
AC_LINK_IFELSE([AC_LANG_PROGRAM([
AC_INCLUDES_DEFAULT],
[[int ret = 1;
# if we're cross compiling, just try to compile and figure good enough
if test "$asm_result" = "unknown" ; then
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"])
fi
return ret;
]])],
[asm_result="yes"], [asm_result="no"])
fi

AC_MSG_RESULT([$asm_result])
Expand Down
59 changes: 52 additions & 7 deletions opal/include/opal/sys/powerpc/atomic.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
* Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 2010 IBM Corporation. All rights reserved.
* Copyright (c) 2015 Los Alamos National Security, LLC. All rights
* Copyright (c) 2015-2016 Los Alamos National Security, LLC. All rights
* reserved.
* $COPYRIGHT$
*
Expand Down Expand Up @@ -54,6 +54,9 @@
#define OPAL_HAVE_ATOMIC_CMPSET_64 1
#define OPAL_HAVE_ATOMIC_SWAP_64 1
#define OPAL_HAVE_ATOMIC_LLSC_64 1
#define OPAL_HAVE_ATOMIC_MATH_64 1
#define OPAL_HAVE_ATOMIC_ADD_64 1
#define OPAL_HAVE_ATOMIC_SUB_64 1
#endif


Expand Down Expand Up @@ -121,6 +124,16 @@ void opal_atomic_wmb(void)
#define OPAL_ASM_ADDR(a) (a)
#endif

#if defined(__PGI)
/* work-around for bug in PGI 16.5-16.7 where the compiler fails to
* correctly emit load instructions for 64-bit operands. without this
* it will emit lwz instead of ld to load the 64-bit operand. */
#define OPAL_ASM_VALUE64(x) (void *)(intptr_t) (x)
#else
#define OPAL_ASM_VALUE64(x) x
#endif


static inline int opal_atomic_cmpset_32(volatile int32_t *addr,
int32_t oldval, int32_t newval)
{
Expand Down Expand Up @@ -210,6 +223,38 @@ static inline int32_t opal_atomic_swap_32(volatile int32_t *addr, int32_t newval
#if (OPAL_ASSEMBLY_ARCH == OPAL_POWERPC64)

#if OPAL_GCC_INLINE_ASSEMBLY
static inline int64_t opal_atomic_add_64 (volatile int64_t* v, int64_t inc)
{
int64_t t;

__asm__ __volatile__("1: ldarx %0, 0, %3 \n\t"
" add %0, %2, %0 \n\t"
" stdcx. %0, 0, %3 \n\t"
" bne- 1b \n\t"
: "=&r" (t), "=m" (*v)
: "r" (OPAL_ASM_VALUE64(inc)), "r" OPAL_ASM_ADDR(v)
: "cc");

return t;
}


static inline int64_t opal_atomic_sub_64 (volatile int64_t* v, int64_t dec)
{
int64_t t;

__asm__ __volatile__(
"1: ldarx %0,0,%3 \n\t"
" subf %0,%2,%0 \n\t"
" stdcx. %0,0,%3 \n\t"
" bne- 1b \n\t"
: "=&r" (t), "=m" (*v)
: "r" (OPAL_ASM_VALUE64(dec)), "r" OPAL_ASM_ADDR(v)
: "cc");

return t;
}

static inline int opal_atomic_cmpset_64(volatile int64_t *addr,
int64_t oldval, int64_t newval)
{
Expand All @@ -223,7 +268,7 @@ static inline int opal_atomic_cmpset_64(volatile int64_t *addr,
" bne- 1b \n\t"
"2:"
: "=&r" (ret), "=m" (*addr)
: "r" (addr), "r" (oldval), "r" (newval), "m" (*addr)
: "r" (addr), "r" (OPAL_ASM_VALUE64(oldval)), "r" (OPAL_ASM_VALUE64(newval))
: "cc", "memory");

return (ret == oldval);
Expand All @@ -242,15 +287,15 @@ static inline int64_t opal_atomic_ll_64(volatile int64_t *addr)

static inline int opal_atomic_sc_64(volatile int64_t *addr, int64_t newval)
{
int32_t ret, foo;
int32_t ret;

__asm__ __volatile__ (" stdcx. %4, 0, %3 \n\t"
__asm__ __volatile__ (" stdcx. %2, 0, %1 \n\t"
" li %0,0 \n\t"
" bne- 1f \n\t"
" ori %0,%0,1 \n\t"
"1:"
: "=r" (ret), "=m" (*addr), "=r" (foo)
: "r" (addr), "r" (newval)
: "=r" (ret)
: "r" (addr), "r" (OPAL_ASM_VALUE64(newval))
: "cc", "memory");
return ret;
}
Expand Down Expand Up @@ -287,7 +332,7 @@ static inline int64_t opal_atomic_swap_64(volatile int64_t *addr, int64_t newval
" stdcx. %3, 0, %2 \n\t"
" bne- 1b \n\t"
: "=&r" (ret), "=m" (*addr)
: "r" (addr), "r" (newval)
: "r" (addr), "r" (OPAL_ASM_VALUE64(newval))
: "cc", "memory");

return ret;
Expand Down