|
30 | 30 | #define OPAL_HAVE_ATOMIC_MEM_BARRIER 1 |
31 | 31 | #define OPAL_HAVE_ATOMIC_LLSC_32 1 |
32 | 32 | #define OPAL_HAVE_ATOMIC_CMPSET_32 1 |
| 33 | +#define OPAL_HAVE_ATOMIC_SWAP_32 1 |
33 | 34 | #define OPAL_HAVE_ATOMIC_MATH_32 1 |
34 | 35 | #define OPAL_HAVE_ATOMIC_CMPSET_64 1 |
| 36 | +#define OPAL_HAVE_ATOMIC_SWAP_64 1 |
35 | 37 | #define OPAL_HAVE_ATOMIC_LLSC_64 1 |
36 | 38 | #define OPAL_HAVE_ATOMIC_ADD_32 1 |
37 | 39 | #define OPAL_HAVE_ATOMIC_SUB_32 1 |
@@ -92,6 +94,20 @@ static inline int opal_atomic_cmpset_32(volatile int32_t *addr, |
92 | 94 | return (ret == oldval); |
93 | 95 | } |
94 | 96 |
|
| 97 | +static inline int32_t opal_atomic_swap_32(volatile int32_t *addr, int32_t newval) |
| 98 | +{ |
| 99 | + int32_t ret, tmp; |
| 100 | + |
| 101 | + __asm__ __volatile__ ("1: ldaxr %w0, [%2] \n" |
| 102 | + " stlxr %w1, %w3, [%2] \n" |
| 103 | + " cbnz %w1, 1b \n" |
| 104 | + : "=&r" (ret), "=&r" (tmp) |
| 105 | + : "r" (addr), "r" (newval) |
| 106 | + : "cc", "memory"); |
| 107 | + |
| 108 | + return ret; |
| 109 | +} |
| 110 | + |
95 | 111 | /* these two functions aren't inlined in the non-gcc case because then |
96 | 112 | there would be two function calls (since neither cmpset_32 nor |
97 | 113 | atomic_?mb can be inlined). Instead, we "inline" them by hand in |
@@ -176,6 +192,21 @@ static inline int opal_atomic_cmpset_64(volatile int64_t *addr, |
176 | 192 | return (ret == oldval); |
177 | 193 | } |
178 | 194 |
|
| 195 | +static inline int64_t opal_atomic_swap_64 (volatile int64_t *addr, int64_t newval) |
| 196 | +{ |
| 197 | + int64_t ret; |
| 198 | + int tmp; |
| 199 | + |
| 200 | + __asm__ __volatile__ ("1: ldaxr %0, [%2] \n" |
| 201 | + " stlxr %w1, %3, [%2] \n" |
| 202 | + " cbnz %w1, 1b \n" |
| 203 | + : "=&r" (ret), "=&r" (tmp) |
| 204 | + : "r" (addr), "r" (newval) |
| 205 | + : "cc", "memory"); |
| 206 | + |
| 207 | + return ret; |
| 208 | +} |
| 209 | + |
179 | 210 | /* these two functions aren't inlined in the non-gcc case because then |
180 | 211 | there would be two function calls (since neither cmpset_64 nor |
181 | 212 | atomic_?mb can be inlined). Instead, we "inline" them by hand in |
|
0 commit comments