11
11
* Copyright (c) 2004-2005 The Regents of the University of California.
12
12
* All rights reserved.
13
13
* 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
15
15
* reserved.
16
16
* $COPYRIGHT$
17
17
*
55
55
#define OPAL_HAVE_ATOMIC_CMPSET_64 1
56
56
#define OPAL_HAVE_ATOMIC_SWAP_64 1
57
57
#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
58
61
#endif
59
62
60
63
@@ -128,6 +131,16 @@ void opal_atomic_isync(void)
128
131
#define OPAL_ASM_ADDR (a ) (a)
129
132
#endif
130
133
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
+
131
144
static inline int opal_atomic_cmpset_32 (volatile int32_t * addr ,
132
145
int32_t oldval , int32_t newval )
133
146
{
@@ -217,6 +230,38 @@ static inline int32_t opal_atomic_swap_32(volatile int32_t *addr, int32_t newval
217
230
#if (OPAL_ASSEMBLY_ARCH == OPAL_POWERPC64 )
218
231
219
232
#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
+
220
265
static inline int opal_atomic_cmpset_64 (volatile int64_t * addr ,
221
266
int64_t oldval , int64_t newval )
222
267
{
@@ -229,8 +274,8 @@ static inline int opal_atomic_cmpset_64(volatile int64_t *addr,
229
274
" stdcx. %4, 0, %2 \n\t"
230
275
" bne- 1b \n\t"
231
276
"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 ))
234
279
: "cc" , "memory" );
235
280
236
281
return (ret == oldval );
@@ -249,15 +294,15 @@ static inline int64_t opal_atomic_ll_64(volatile int64_t *addr)
249
294
250
295
static inline int opal_atomic_sc_64 (volatile int64_t * addr , int64_t newval )
251
296
{
252
- int32_t ret , foo ;
297
+ int32_t ret ;
253
298
254
- __asm__ __volatile__ (" stdcx. %4 , 0, %3 \n\t"
299
+ __asm__ __volatile__ (" stdcx. %2 , 0, %1 \n\t"
255
300
" li %0,0 \n\t"
256
301
" bne- 1f \n\t"
257
302
" ori %0,%0,1 \n\t"
258
303
"1:"
259
- : "=r" (ret ), "=m" ( * addr ), "=r" ( foo )
260
- : "r" (addr ), "r" (newval )
304
+ : "=r" (ret )
305
+ : "r" (addr ), "r" (OPAL_ASM_VALUE64 ( newval ) )
261
306
: "cc" , "memory" );
262
307
return ret ;
263
308
}
@@ -294,7 +339,7 @@ static inline int64_t opal_atomic_swap_64(volatile int64_t *addr, int64_t newval
294
339
" stdcx. %3, 0, %2 \n\t"
295
340
" bne- 1b \n\t"
296
341
: "=&r" (ret ), "=m" (* addr )
297
- : "r" (addr ), "r" (newval )
342
+ : "r" (addr ), "r" (OPAL_ASM_VALUE64 ( newval ) )
298
343
: "cc" , "memory" );
299
344
300
345
return ret ;
0 commit comments