1111 * Copyright (c) 2004-2005 The Regents of the University of California.
1212 * All rights reserved.
1313 * Copyright (c) 2010 IBM Corporation. All rights reserved.
14- * Copyright (c) 2015 Los Alamos National Security, LLC. All rights
14+ * Copyright (c) 2015-2016 Los Alamos National Security, LLC. All rights
1515 * reserved.
1616 * $COPYRIGHT$
1717 *
5555#define OPAL_HAVE_ATOMIC_CMPSET_64 1
5656#define OPAL_HAVE_ATOMIC_SWAP_64 1
5757#define OPAL_HAVE_ATOMIC_LLSC_64 1
58+ #define OPAL_HAVE_ATOMIC_MATH_64 1
59+ #define OPAL_HAVE_ATOMIC_ADD_64 1
60+ #define OPAL_HAVE_ATOMIC_SUB_64 1
5861#endif
5962
6063
@@ -128,6 +131,16 @@ void opal_atomic_isync(void)
128131#define OPAL_ASM_ADDR (a ) (a)
129132#endif
130133
134+ #if defined(__PGI )
135+ /* work-around for bug in PGI 16.5-16.7 where the compiler fails to
136+ * correctly emit load instructions for 64-bit operands. without this
137+ * it will emit lwz instead of ld to load the 64-bit operand. */
138+ #define OPAL_ASM_VALUE64 (x ) (void *)(intptr_t) (x)
139+ #else
140+ #define OPAL_ASM_VALUE64 (x ) x
141+ #endif
142+
143+
131144static inline int opal_atomic_cmpset_32 (volatile int32_t * addr ,
132145 int32_t oldval , int32_t newval )
133146{
@@ -217,6 +230,38 @@ static inline int32_t opal_atomic_swap_32(volatile int32_t *addr, int32_t newval
217230#if (OPAL_ASSEMBLY_ARCH == OPAL_POWERPC64 )
218231
219232#if OPAL_GCC_INLINE_ASSEMBLY
233+ static inline int64_t opal_atomic_add_64 (volatile int64_t * v , int64_t inc )
234+ {
235+ int64_t t ;
236+
237+ __asm__ __volatile__("1: ldarx %0, 0, %3 \n\t"
238+ " add %0, %2, %0 \n\t"
239+ " stdcx. %0, 0, %3 \n\t"
240+ " bne- 1b \n\t"
241+ : "=&r" (t ), "+m" (* v )
242+ : "r" (OPAL_ASM_VALUE64 (inc )), "r" OPAL_ASM_ADDR (v )
243+ : "cc" );
244+
245+ return t ;
246+ }
247+
248+
249+ static inline int64_t opal_atomic_sub_64 (volatile int64_t * v , int64_t dec )
250+ {
251+ int64_t t ;
252+
253+ __asm__ __volatile__(
254+ "1: ldarx %0,0,%3 \n\t"
255+ " subf %0,%2,%0 \n\t"
256+ " stdcx. %0,0,%3 \n\t"
257+ " bne- 1b \n\t"
258+ : "=&r" (t ), "+m" (* v )
259+ : "r" (OPAL_ASM_VALUE64 (dec )), "r" OPAL_ASM_ADDR (v )
260+ : "cc" );
261+
262+ return t ;
263+ }
264+
220265static inline int opal_atomic_cmpset_64 (volatile int64_t * addr ,
221266 int64_t oldval , int64_t newval )
222267{
@@ -229,8 +274,8 @@ static inline int opal_atomic_cmpset_64(volatile int64_t *addr,
229274 " stdcx. %4, 0, %2 \n\t"
230275 " bne- 1b \n\t"
231276 "2:"
232- : "=&r" (ret ), "= m" (* addr )
233- : "r" (addr ), "r" (oldval ), "r" (newval ), "m" ( * addr )
277+ : "=&r" (ret ), "+ m" (* addr )
278+ : "r" (addr ), "r" (OPAL_ASM_VALUE64 ( oldval )) , "r" (OPAL_ASM_VALUE64 ( newval ))
234279 : "cc" , "memory" );
235280
236281 return (ret == oldval );
@@ -249,15 +294,15 @@ static inline int64_t opal_atomic_ll_64(volatile int64_t *addr)
249294
250295static inline int opal_atomic_sc_64 (volatile int64_t * addr , int64_t newval )
251296{
252- int32_t ret , foo ;
297+ int32_t ret ;
253298
254- __asm__ __volatile__ (" stdcx. %4 , 0, %3 \n\t"
299+ __asm__ __volatile__ (" stdcx. %2 , 0, %1 \n\t"
255300 " li %0,0 \n\t"
256301 " bne- 1f \n\t"
257302 " ori %0,%0,1 \n\t"
258303 "1:"
259- : "=r" (ret ), "=m" ( * addr ), "=r" ( foo )
260- : "r" (addr ), "r" (newval )
304+ : "=r" (ret )
305+ : "r" (addr ), "r" (OPAL_ASM_VALUE64 ( newval ) )
261306 : "cc" , "memory" );
262307 return ret ;
263308}
@@ -294,7 +339,7 @@ static inline int64_t opal_atomic_swap_64(volatile int64_t *addr, int64_t newval
294339 " stdcx. %3, 0, %2 \n\t"
295340 " bne- 1b \n\t"
296341 : "=&r" (ret ), "=m" (* addr )
297- : "r" (addr ), "r" (newval )
342+ : "r" (addr ), "r" (OPAL_ASM_VALUE64 ( newval ) )
298343 : "cc" , "memory" );
299344
300345 return ret ;
0 commit comments