1# ast atomic scalar operations feature tests 2 3if aso note{ gcc 4.1+ 64 bit memory atomic operations model }end link{ 4 #include "FEATURE/common" 5 int main() 6 { 7 uint64_t i = 0; 8 return __sync_fetch_and_add(&i,7); 9 } 10 }end && { 11 #define _aso_cas8(p,o,n) __sync_val_compare_and_swap(p,o,n) 12 #define _aso_inc8(p) __sync_fetch_and_add(p,1) 13 #define _aso_dec8(p) __sync_fetch_and_sub(p,1) 14 #define _aso_cas16(p,o,n) __sync_val_compare_and_swap(p,o,n) 15 #define _aso_inc16(p) __sync_fetch_and_add(p,1) 16 #define _aso_dec16(p) __sync_fetch_and_sub(p,1) 17 #define _aso_cas32(p,o,n) __sync_val_compare_and_swap(p,o,n) 18 #define _aso_inc32(p) __sync_fetch_and_add(p,1) 19 #define _aso_dec32(p) __sync_fetch_and_sub(p,1) 20 #define _aso_cas64(p,o,n) __sync_val_compare_and_swap(p,o,n) 21 #define _aso_inc64(p) __sync_fetch_and_add(p,1) 22 #define _aso_dec64(p) __sync_fetch_and_sub(p,1) 23 #if _ast_sizeof_pointer == 8 24 #define _aso_casptr(p,o,n) ((void*)__sync_val_compare_and_swap(p,(uint64_t)o,(uint64_t)n)) 25 #else 26 #define _aso_casptr(p,o,n) ((void*)__sync_val_compare_and_swap(p,(uint32_t)o,(uint32_t)n)) 27 #endif 28 } 29elif aso note{ gcc 4.1+ 32 bit memory atomic operations model }end link{ 30 #include "FEATURE/common" 31 int main() 32 { 33 uint32_t i = 0; 34 return __sync_fetch_and_add(&i,7); 35 } 36 }end && { 37 #define _aso_cas8(p,o,n) __sync_val_compare_and_swap(p,o,n) 38 #define _aso_inc8(p) __sync_fetch_and_add(p,1) 39 #define _aso_dec8(p) __sync_fetch_and_sub(p,1) 40 #define _aso_cas16(p,o,n) __sync_val_compare_and_swap(p,o,n) 41 #define _aso_inc16(p) __sync_fetch_and_add(p,1) 42 #define _aso_dec16(p) __sync_fetch_and_sub(p,1) 43 #define _aso_cas32(p,o,n) __sync_val_compare_and_swap(p,o,n) 44 #define _aso_inc32(p) __sync_fetch_and_add(p,1) 45 #define _aso_dec32(p) __sync_fetch_and_sub(p,1) 46 #define _aso_casptr(p,o,n) ((void*)__sync_val_compare_and_swap(p,(uint32_t)o,(uint32_t)n)) 47 } 48elif aso note{ <atomic.h> atomic_cas_64 }end link{ 49 #include "FEATURE/common" 50 #include <atomic.h> 51 int main() 52 { 53 uint64_t i = 0; 54 uint32_t j = 1; 55 return atomic_cas_64(&i, 0, 1) != 0 || atomic_add_32_nv(&j, 1) != 1; 56 } 57 }end && { 58 #include <atomic.h> 59 #define _aso_cas8(p,o,n) atomic_cas_8(p,o,n) 60 #define _aso_inc8(p) (atomic_add_8_nv(p,1)-1) 61 #define _aso_dec8(p) (atomic_add_8_nv(p,-1)+1) 62 #define _aso_cas16(p,o,n) atomic_cas_16(p,o,n) 63 #define _aso_inc16(p) (atomic_add_16_nv(p,1)-1) 64 #define _aso_dec16(p) (atomic_add_16_nv(p,-1)+1) 65 #define _aso_cas32(p,o,n) atomic_cas_32(p,o,n) 66 #define _aso_inc32(p) (atomic_add_32_nv(p,1)-1) 67 #define _aso_dec32(p) (atomic_add_32_nv(p,-1)+1) 68 #define _aso_cas64(p,o,n) atomic_cas_64(p,o,n) 69 #define _aso_inc64(p) (atomic_add_64_nv(p,1)-1) 70 #define _aso_dec64(p) (atomic_add_64_nv(p,-1)+1) 71 #if _ast_sizeof_pointer == 8 72 #define _aso_casptr(p,o,n) ((void*)atomic_cas_64((uint64_t*)p,(uint64_t)o,(uint64_t)n)) 73 #else 74 #define _aso_casptr(p,o,n) ((void*)atomic_cas_32((uint32_t*)p,(uint32_t)o,(uint32_t)n)) 75 #endif 76 } 77elif aso note{ <atomic.h> atomic_cas_32 }end link{ 78 #include "FEATURE/common" 79 #include <atomic.h> 80 int main() 81 { 82 uint32_t i = 0; 83 return atomic_cas_32(&i, 0, 1) != 0 || (atomic_add_32_nv(&i, 1) - 1) != 1; 84 } 85 }end && { 86 #include <atomic.h> 87 #define _aso_cas8(p,o,n) atomic_cas_8(p,o,n) 88 #define _aso_inc8(p) (atomic_add_8_nv(p,1)-1) 89 #define _aso_dec8(p) (atomic_add_8_nv(p,-1)+1) 90 #define _aso_cas16(p,o,n) atomic_cas_16(p,o,n) 91 #define _aso_inc16(p) (atomic_add_16_nv(p,1)-1) 92 #define _aso_dec16(p) (atomic_add_16_nv(p,-1)+1) 93 #define _aso_cas32(p,o,n) atomic_cas_32(p,o,n) 94 #define _aso_inc32(p) (atomic_add_32_nv(p,1)-1) 95 #define _aso_dec32(p) (atomic_add_32_nv(p,-1)+1) 96 #define _aso_casptr(p,o,n) ((void*)atomic_cas_32((uint32_t*)p,(uint32_t)o,(uint32_t)n)) 97 } 98elif aso -latomic note{ <atomic.h> atomic_cas_64 with -latomic }end link{ 99 #include "FEATURE/common" 100 #include <atomic.h> 101 int main() 102 { 103 uint64_t i = 0; 104 uint32_t j = 1; 105 return atomic_cas_64(&i, 0, 1) != 0 || (atomic_add_32_nv(&j, 1) - 1) != 1; 106 } 107 }end && { 108 #include <atomic.h> 109 #define _REQ_atomic 110 #define _aso_cas8(p,o,n) atomic_cas_8(p,o,n) 111 #define _aso_inc8(p) (atomic_add_8_nv(p,1)-1) 112 #define _aso_dec8(p) (atomic_add_8_nv(p,-1)+1) 113 #define _aso_cas16(p,o,n) atomic_cas_16(p,o,n) 114 #define _aso_inc16(p) (atomic_add_16_nv(p,1)-1) 115 #define _aso_dec16(p) (atomic_add_16_nv(p,-1)+1) 116 #define _aso_cas32(p,o,n) atomic_cas_32(p,o,n) 117 #define _aso_inc32(p) (atomic_add_32_nv(p,1)-1) 118 #define _aso_dec32(p) (atomic_add_32_nv(p,-1)+1) 119 #define _aso_cas64(p,o,n) atomic_cas_64(p,o,n) 120 #define _aso_inc64(p) (atomic_add_64_nv(p,1)-1) 121 #define _aso_dec64(p) (atomic_add_64_nv(p,-1)+1) 122 #if _ast_sizeof_pointer == 8 123 #define _aso_casptr(p,o,n) ((void*)atomic_cas_64((uint64_t*)p,(uint64_t)o,(uint64_t)n)) 124 #else 125 #define _aso_casptr(p,o,n) ((void*)atomic_cas_32((uint32_t*)p,(uint32_t)o,(uint32_t)n)) 126 #endif 127 } 128elif aso note{ <atomic.h> atomic_cas_32 with -latomic }end link{ 129 #include "FEATURE/common" 130 #include <atomic.h> 131 int main() 132 { 133 uint32_t i = 0; 134 return atomic_cas_32(&i, 0, 1) != 0 || (atomic_add_32_nv(&i, 1) - 1) != 1; 135 } 136 }end && { 137 #include <atomic.h> 138 #define _REQ_atomic 139 #define _aso_cas8(p,o,n) atomic_cas_8(p,o,n) 140 #define _aso_inc8(p) (atomic_add_8_nv(p,1)-1) 141 #define _aso_dec8(p) (atomic_add_8_nv(p,-1)+1) 142 #define _aso_cas16(p,o,n) atomic_cas_16(p,o,n) 143 #define _aso_inc16(p) (atomic_add_16_nv(p,1)-1) 144 #define _aso_dec16(p) (atomic_add_16_nv(p,-1)+1) 145 #define _aso_cas32(p,o,n) atomic_cas_32(p,o,n) 146 #define _aso_inc32(p) (atomic_add_32_nv(p,1)-1) 147 #define _aso_dec32(p) (atomic_add_32_nv(p,-1)+1) 148 #define _aso_casptr(p,o,n) ((void*)atomic_cas_32((uint32_t*)p,(uint32_t)o,(uint32_t)n)) 149 } 150elif aso note{ <atomic.h> cas64 }end link{ 151 #include "FEATURE/common" 152 #include <atomic.h> 153 int main() 154 { 155 uint64_t i = 0; 156 uint32_t j = 1; 157 return cas64(&i, 0, 1) != 0 || (atomic_add_32_nv(&j, 1) - 1) != 1; 158 } 159 }end && { 160 #include <atomic.h> 161 #define _aso_cas8(p,o,n) cas8(p,o,n) 162 #define _aso_inc8(p) (atomic_add_8_nv(p,1)-1) 163 #define _aso_dec8(p) (atomic_add_8_nv(p,-1)+1) 164 #define _aso_cas16(p,o,n) cas16(p,o,n) 165 #define _aso_inc16(p) (atomic_add_16_nv(p,1)-1) 166 #define _aso_dec16(p) (atomic_add_16_nv(p,-1)+1) 167 #define _aso_cas32(p,o,n) cas32(p,o,n) 168 #define _aso_inc32(p) (atomic_add_32_nv(p,1)-1) 169 #define _aso_dec32(p) (atomic_add_32_nv(p,-1)+1) 170 #define _aso_cas64(p,o,n) cas64(p,o,n) 171 #define _aso_inc64(p) (atomic_add_64_nv(p,1)-1) 172 #define _aso_dec64(p) (atomic_add_64_nv(p,-1)+1) 173 #if _ast_sizeof_pointer == 8 174 #define _aso_casptr(p,o,n) ((void*)cas64((uint64_t*)p,(uint64_t)o,(uint64_t)n)) 175 #else 176 #define _aso_casptr(p,o,n) ((void*)cas32((uint32_t*)p,(uint32_t)o,(uint32_t)n)) 177 #endif 178 } 179elif aso note{ <atomic.h> just cas64 }end link{ 180 #include "FEATURE/common" 181 #include <atomic.h> 182 int main() 183 { 184 uint64_t i = 0; 185 uint32_t j = 1; 186 uint16_t k = 1; 187 uint8_t l = 1; 188 return cas64(&i, 0, 1) != 0 || cas32(&j, 0, 1) != 0 || cas16(&k, 0, 1) != 0 || cas8(&l, 0, 1) != 0; 189 } 190 }end && { 191 #include <atomic.h> 192 #define _aso_cas8(p,o,n) cas8(p,o,n) 193 #define _aso_cas16(p,o,n) cas16(p,o,n) 194 #define _aso_cas32(p,o,n) cas32(p,o,n) 195 #define _aso_cas64(p,o,n) cas64(p,o,n) 196 #if _ast_sizeof_pointer == 8 197 #define _aso_casptr(p,o,n) ((void*)cas64((uint64_t*)p,(uint64_t)o,(uint64_t)n)) 198 #else 199 #define _aso_casptr(p,o,n) ((void*)cas32((uint32_t*)p,(uint32_t)o,(uint32_t)n)) 200 #endif 201 } 202elif aso note{ <atomic.h> cas32 }end link{ 203 #include "FEATURE/common" 204 #include <atomic.h> 205 int main() 206 { 207 uint32_t i = 0; 208 return cas32(&i, 0, 1) != 0 || (atomic_add_32_nv(&i, 1) - 1) != 1; 209 } 210 }end && { 211 #include <atomic.h> 212 #define _aso_cas8(p,o,n) cas8(p,o,n) 213 #define _aso_inc8(p) (atomic_add_8_nv(p,1)-1) 214 #define _aso_dec8(p) (atomic_add_8_nv(p,-1)+1) 215 #define _aso_cas16(p,o,n) cas16(p,o,n) 216 #define _aso_inc16(p) (atomic_add_16_nv(p,1)-1) 217 #define _aso_dec16(p) (atomic_add_16_nv(p,-1)+1) 218 #define _aso_cas32(p,o,n) cas32(p,o,n) 219 #define _aso_inc32(p) (atomic_add_32_nv(p,1)-1) 220 #define _aso_dec32(p) (atomic_add_32_nv(p,-1)+1) 221 #define _aso_casptr(p,o,n) ((void*)cas32((uint32_t*)p,(uint32_t)o,(uint32_t)n)) 222 } 223elif aso note{ <atomic.h> just cas32 }end link{ 224 #include "FEATURE/common" 225 #include <atomic.h> 226 int main() 227 { 228 uint32_t j = 1; 229 uint16_t k = 1; 230 uint8_t l = 1; 231 return cas32(&j, 0, 1) != 0 || cas16(&k, 0, 1) != 0 || cas8(&l, 0, 1) != 0; 232 } 233 }end && { 234 #include <atomic.h> 235 #define _aso_cas8(p,o,n) cas8(p,o,n) 236 #define _aso_cas16(p,o,n) cas16(p,o,n) 237 #define _aso_cas32(p,o,n) cas32(p,o,n) 238 #define _aso_casptr(p,o,n) ((void*)cas32((uint32_t*)p,(uint32_t)o,(uint32_t)n)) 239 } 240elif aso note{ winix Interlocked }end link{ 241 #include <windows.h> 242 int main() 243 { 244 LONG i = 0; 245 LONGLONG j = 0; 246 return InterlockedCompareExchange(&i, 1, 0) != 0 || 247 InterlockedIncrement(&i) != 1 || 248 InterlockedDecrement(&i) != 2; 249 } 250 }end && { 251 #include <ast_windows.h> 252 #define _aso_cas32(p,o,n) InterlockedCompareExchange((LONG volatile*)p,n,o) 253 #define _aso_inc32(p) (InterlockedIncrement((LONG volatile*)p)-1) 254 #define _aso_dec32(p) (InterlockedDecrement((LONG volatile*)p)+1) 255 #if _X64 256 #define _aso_cas64(p,o,n) InterlockedCompareExchange64((LONGLONG volatile*)p,n,o) 257 #define _aso_inc64(p) (InterlockedIncrement64((LONGLONG volatile*)p)-1) 258 #define _aso_dec64(p) (InterlockedDecrement64((LONGLONG volatile*)p)+1) 259 #define _aso_casptr(p,o,n) ((void*)InterlockedCompareExchange64((LONGLONG volatile*)p,(LONGLONG)n,(LONGLONG)o)) 260 #else 261 #if _BLD_posix 262 #include "dl.h" 263 typedef struct LL_s 264 { 265 LONG a; 266 LONG b; 267 } LL_t; 268 typedef union 269 { 270 LONGLONG i; 271 LL_t ll; 272 } LL_u; 273 274 #define _aso_cas64(p,o,n) _aso_InterlockedCompareExchange64((LONGLONG volatile*)p,n,o) 275 static LONGLONG _aso_InterlockedCompareExchange64_init(LONGLONG volatile*, LONGLONG, LONGLONG); 276 typedef LONGLONG (*_aso_InterlockedCompareExchange64_f)(LONGLONG volatile*, LONGLONG, LONGLONG); 277 static _aso_InterlockedCompareExchange64_f _aso_InterlockedCompareExchange64 = _aso_InterlockedCompareExchange64_init; 278 static LONGLONG _aso_InterlockedCompareExchange64_32(LONGLONG volatile* p, LONGLONG o, LONGLONG n) 279 { 280 LL_t* lp = (LL_t*)p; 281 LL_t* op = (LL_t*)&o; 282 LL_t* np = (LL_t*)&n; 283 LONGLONG r; 284 285 r = *p; 286 if (_aso_cas32(&lp->a, op->a, np->a) == op->a) 287 { 288 if (_aso_cas32(&lp->b, op->b, np->b) == op->b) 289 return o; 290 _aso_cas32(&lp->a, np->a, op->a); 291 } 292 return r; 293 } 294 static LONGLONG _aso_InterlockedCompareExchange64_init(LONGLONG volatile* p, LONGLONG o, LONGLONG n) 295 { 296 if (!(_aso_InterlockedCompareExchange64 = (_aso_InterlockedCompareExchange64_f)getsymbol(MODULE_kernel, "InterlockedCompareExchange64"))) 297 _aso_InterlockedCompareExchange64 = _aso_InterlockedCompareExchange64_32; 298 return _aso_InterlockedCompareExchange64(p, o, n); 299 } 300 301 #define _aso_inc64(p) (_aso_InterlockedIncrement64((LONGLONG volatile*)p)-1) 302 typedef LONGLONG (*_aso_InterlockedIncrement64_f)(LONGLONG volatile*); 303 static LONGLONG _aso_InterlockedIncrement64_init(LONGLONG volatile*); 304 static _aso_InterlockedIncrement64_f _aso_InterlockedIncrement64 = _aso_InterlockedIncrement64_init; 305 static LONGLONG _aso_InterlockedIncrement64_32(LONGLONG volatile* p) 306 { 307 LONGLONG o; 308 309 do 310 { 311 o = *p; 312 } while (_aso_InterlockedCompareExchange64_32(p, o, o + 1) != o); 313 return o; 314 } 315 static LONGLONG _aso_InterlockedIncrement64_init(LONGLONG volatile* p) 316 { 317 if (!(_aso_InterlockedIncrement64 = (_aso_InterlockedIncrement64_f)getsymbol(MODULE_kernel, "InterlockedIncrement64"))) 318 _aso_InterlockedIncrement64 = _aso_InterlockedIncrement64_32; 319 return _aso_InterlockedIncrement64(p); 320 } 321 322 #define _aso_dec64(p) (_aso_InterlockedDecrement64((LONGLONG volatile*)p)+1) 323 typedef LONGLONG (*_aso_InterlockedDecrement64_f)(LONGLONG volatile*); 324 static LONGLONG _aso_InterlockedDecrement64_init(LONGLONG volatile*); 325 static _aso_InterlockedDecrement64_f _aso_InterlockedDecrement64 = _aso_InterlockedDecrement64_init; 326 static LONGLONG _aso_InterlockedDecrement64_32(LONGLONG volatile* p) 327 { 328 LONGLONG o; 329 330 do 331 { 332 o = *p; 333 } while (_aso_InterlockedCompareExchange64_32(p, o, o - 1) != o); 334 return o; 335 } 336 static LONGLONG _aso_InterlockedDecrement64_init(LONGLONG volatile* p) 337 { 338 if (!(_aso_InterlockedDecrement64 = (_aso_InterlockedDecrement64_f)getsymbol(MODULE_kernel, "InterlockedDecrement64"))) 339 _aso_InterlockedDecrement64 = _aso_InterlockedDecrement64_32; 340 return _aso_InterlockedDecrement64(p); 341 } 342 #endif 343 #define _aso_casptr(p,o,n) ((void*)InterlockedCompareExchange((LONG volatile*)p,(LONG)n,(LONG)o)) 344 #endif 345 } 346elif aso note{ aix fetch and add }end link{ 347 #include <sys/atomic_op.h> 348 int main() 349 { 350 int i = 0; 351 return fetch_and_add((atomic_p)&i,1); 352 } 353 }end && { 354 #include <sys/atomic_op.h> 355 #define _aso_incint(p) fetch_and_add((atomic_p)p,1) 356 #define _aso_decint(p) fetch_and_add((atomic_p)p,-1) 357 #define _aso_casint(p,o,n) (compare_and_swap((atomic_p)p,(int*)&o,(int)n) ? o : *p) 358 #if _ast_sizeof_pointer == 8 359 #define _aso_casptr(p,o,n) (compare_and_swaplp((atomic_l)p,(long*)&o,(long)n) ? o : *(void**)p) 360 #else 361 #define _aso_casptr(p,o,n) (compare_and_swap((atomic_p)p,(int*)&o,(int)n) ? o : *(void**)p) 362 #endif 363 } 364elif aso note{ mips compare and swap }end link{ 365 int main() 366 { 367 int i = 1; 368 return __compare_and_swap(&i, 0, 1) != 1; 369 } 370 }end && { 371 #define _aso_cas32(p,o,n) (__compare_and_swap(p,o,n) ? o : *p) 372 #define _aso_casptr(p,o,n) (__compare_and_swap((long*)p,(long)o,(long)n) ? o : *(void**)p) 373 } 374elif aso note{ i386|i386-64 asm compare and swap }end link{ 375 #include "FEATURE/common" 376 377 static uint32_t 378 cas32(uint32_t volatile* p, uint32_t o, uint32_t n) 379 { 380 uint32_t r; 381 382 __asm__ __volatile__ ( 383 "lock ; cmpxchg %3,%4" 384 : "=a"(r), "=m"(*p) 385 : "0"(o), "q"(n), "m"(*p) 386 : "memory", "cc" 387 ); 388 return r; 389 } 390 391 #if _ast_sizeof_pointer == 8 392 393 static uint64_t 394 cas64(uint64_t volatile* p, uint64_t o, uint64_t n) 395 { 396 uint64_t r; 397 398 __asm__ __volatile__ ( 399 "lock ; cmpxchg %3,%4" 400 : "=a"(r), "=m"(*p) 401 : "0"(o), "q"(n), "m"(*p) 402 : "memory", "cc" 403 ); 404 return r; 405 } 406 407 #else 408 409 #define cas64(p,o,n) (*(p)) 410 411 #endif 412 413 int main() 414 { 415 uint32_t i = 0; 416 uint64_t j = 0; 417 return cas32(&i, 0, 1) || cas64(&j, 0, 1); 418 } 419 }end && { 420 static uint32_t 421 cas32(uint32_t volatile* p, uint32_t o, uint32_t n) 422 { 423 uint32_t r; 424 425 __asm__ __volatile__ ( 426 "lock ; cmpxchg %3,%4" 427 : "=a"(r), "=m"(*p) 428 : "0"(o), "q"(n), "m"(*p) 429 : "memory", "cc" 430 ); 431 return r; 432 } 433 434 #if _ast_sizeof_pointer == 8 435 436 static uint64_t 437 cas64(uint64_t volatile* p, uint64_t o, uint64_t n) 438 { 439 uint64_t r; 440 441 __asm__ __volatile__ ( 442 "lock ; cmpxchg %3,%4" 443 : "=a"(r), "=m"(*p) 444 : "0"(o), "q"(n), "m"(*p) 445 : "memory", "cc" 446 ); 447 return r; 448 } 449 450 #endif 451 452 #define _aso_cas32(p,o,n) cas32(p,o,n) 453 #if _ast_sizeof_pointer == 8 454 #define _aso_cas64(p,o,n) cas64(p,o,n) 455 #define _aso_casptr(p,o,n) ((void*)cas64((uint64_t*)p,(uint64_t)o,(uint64_t)n)) 456 #else 457 #define _aso_casptr(p,o,n) ((void*)cas32((uint32_t*)p,(uint32_t)o,(uint32_t)n)) 458 #endif 459 } 460elif aso note{ ia64 asm compare and swap }end link{ 461 #include "FEATURE/common" 462 463 static uint32_t 464 cas32(uint32_t volatile* p, uint32_t o, uint32_t n) 465 { 466 uint32_t r; 467 468 __asm__ __volatile__ ( 469 "zxt4 %3=%3 ;; mov ar.ccv=%3 ;; cmpxchg4.acq %0=%1,%2,ar.ccv" 470 : "=r"(r), "+S"(*p) 471 : "r"(n), "r"(o) : "memory" 472 ); 473 return r; 474 } 475 476 static uint64_t 477 cas64(uint64_t volatile* p, uint64_t o, uint64_t n) 478 { 479 uint64_t r; 480 481 __asm__ __volatile__ ( 482 "mov ar.ccv=%3 ;; cmpxchg8.acq %0=%1,%2,ar.ccv" 483 : "=r"(r), "+S"(*p) 484 : "r"(n), "r"(o) : "memory" 485 ); 486 return r; 487 } 488 489 int main() 490 { 491 uint32_t i = 0; 492 uint64_t j = 0; 493 return cas32(&i, 0, 1) || cas64(&j, 0, 1); 494 } 495 }end && { 496 static uint32_t 497 cas32(uint32_t volatile* p, uint32_t o, uint32_t n) 498 { 499 uint32_t r; 500 501 __asm__ __volatile__ ( 502 "zxt4 %3=%3 ;; mov ar.ccv=%3 ;; cmpxchg4.acq %0=%1,%2,ar.ccv" 503 : "=r"(r), "+S"(*p) 504 : "r"(n), "r"(o) : "memory" 505 ); 506 return r; 507 } 508 509 static uint64_t 510 cas64(uint64_t volatile* p, uint64_t o, uint64_t n) 511 { 512 uint64_t r; 513 514 __asm__ __volatile__ ( 515 "mov ar.ccv=%3 ;; cmpxchg8.acq %0=%1,%2,ar.ccv" 516 : "=r"(r), "+S"(*p) 517 : "r"(n), "r"(o) : "memory" 518 ); 519 return r; 520 } 521 522 #define _aso_cas32(p,o,n) cas32(p,o,n) 523 #define _aso_cas64(p,o,n) cas64(p,o,n) 524 #if _ast_sizeof_pointer == 8 525 #define _aso_casptr(p,o,n) ((void*)cas64((uint64_t*)p,(uint64_t)o,(uint64_t)n)) 526 #else 527 #define _aso_casptr(p,o,n) ((void*)cas32((uint32_t*)p,(uint32_t)o,(uint32_t)n)) 528 #endif 529 } 530elif aso note{ ppc asm compare and swap }end link{ 531 #include "FEATURE/common" 532 533 static uint32_t 534 cas32(uint32_t volatile* p, uint32_t o, uint32_t n) 535 { 536 int r; 537 538 __asm__ __volatile__ ( 539 "0: lwarx %0,0,%1 ;" 540 " xor. %0,%3,%0;" 541 " bne 1f;" 542 " stwcx. %2,0,%1;" 543 " bne- 0b;" 544 "1:" 545 : "=&r"(r) 546 : "r"(p), "r"(n), "r"(o) 547 : "cr0", "memory" 548 ); 549 __asm__ __volatile__ ("isync" : : : "memory"); 550 return r ? *p : o; 551 } 552 553 static uint64_t 554 cas64(uint64_t volatile* p, uint64_t o, uint64_t n) 555 { 556 long r; 557 558 __asm__ __volatile__ ( 559 "0: ldarx %0,0,%1 ;" 560 " xor. %0,%3,%0;" 561 " bne 1f;" 562 " stdcx. %2,0,%1;" 563 " bne- 0b;" 564 "1:" 565 : "=&r"(r) 566 : "r"(p), "r"(n), "r"(o) 567 : "cr0", "memory" 568 ); 569 __asm__ __volatile__ ("isync" : : : "memory"); 570 return r ? *p : o; 571 } 572 573 int main() 574 { 575 uint32_t i = 0; 576 uint64_t j = 0; 577 return cas32(&i, 0, 1) || cas64(&j, 0, 1); 578 } 579 }end && { 580 static uint32_t 581 cas32(uint32_t volatile* p, uint32_t o, uint32_t n) 582 { 583 int r; 584 585 __asm__ __volatile__ ( 586 "0: lwarx %0,0,%1 ;" 587 " xor. %0,%3,%0;" 588 " bne 1f;" 589 " stwcx. %2,0,%1;" 590 " bne- 0b;" 591 "1:" 592 : "=&r"(r) 593 : "r"(p), "r"(n), "r"(o) 594 : "cr0", "memory" 595 ); 596 __asm__ __volatile__ ("isync" : : : "memory"); 597 return r ? *p : o; 598 } 599 600 static uint64_t 601 cas64(uint64_t volatile* p, uint64_t o, uint64_t n) 602 { 603 long r; 604 605 __asm__ __volatile__ ( 606 "0: ldarx %0,0,%1 ;" 607 " xor. %0,%3,%0;" 608 " bne 1f;" 609 " stdcx. %2,0,%1;" 610 " bne- 0b;" 611 "1:" 612 : "=&r"(r) 613 : "r"(p), "r"(n), "r"(o) 614 : "cr0", "memory" 615 ); 616 __asm__ __volatile__ ("isync" : : : "memory"); 617 return r ? *p : o; 618 } 619 620 #define _aso_cas32(p,o,n) cas32(p,o,n) 621 #define _aso_cas64(p,o,n) cas64(p,o,n) 622 #if _ast_sizeof_pointer == 8 623 #define _aso_casptr(p,o,n) ((void*)cas64((uint64_t*)p,(uint64_t)o,(uint64_t)n)) 624 #else 625 #define _aso_casptr(p,o,n) ((void*)cas32((uint32_t*)p,(uint32_t)o,(uint32_t)n)) 626 #endif 627 } 628endif 629