|
296 | 296 | arch_cmpxchg_release((ptr), (o), (n)); \
|
297 | 297 | })
|
298 | 298 |
|
| 299 | +#if defined(CONFIG_64BIT) && defined(CONFIG_RISCV_ISA_ZACAS) |
| 300 | + |
| 301 | +#define system_has_cmpxchg128() riscv_has_extension_unlikely(RISCV_ISA_EXT_ZACAS) |
| 302 | + |
| 303 | +union __u128_halves { |
| 304 | + u128 full; |
| 305 | + struct { |
| 306 | + u64 low, high; |
| 307 | + }; |
| 308 | +}; |
| 309 | + |
| 310 | +#define __arch_cmpxchg128(p, o, n, cas_sfx) \ |
| 311 | +({ \ |
| 312 | + __typeof__(*(p)) __o = (o); \ |
| 313 | + union __u128_halves __hn = { .full = (n) }; \ |
| 314 | + union __u128_halves __ho = { .full = (__o) }; \ |
| 315 | + register unsigned long t1 asm ("t1") = __hn.low; \ |
| 316 | + register unsigned long t2 asm ("t2") = __hn.high; \ |
| 317 | + register unsigned long t3 asm ("t3") = __ho.low; \ |
| 318 | + register unsigned long t4 asm ("t4") = __ho.high; \ |
| 319 | + \ |
| 320 | + __asm__ __volatile__ ( \ |
| 321 | + " amocas.q" cas_sfx " %0, %z3, %2" \ |
| 322 | + : "+&r" (t3), "+&r" (t4), "+A" (*(p)) \ |
| 323 | + : "rJ" (t1), "rJ" (t2) \ |
| 324 | + : "memory"); \ |
| 325 | + \ |
| 326 | + ((u128)t4 << 64) | t3; \ |
| 327 | +}) |
| 328 | + |
| 329 | +#define arch_cmpxchg128(ptr, o, n) \ |
| 330 | + __arch_cmpxchg128((ptr), (o), (n), ".aqrl") |
| 331 | + |
| 332 | +#define arch_cmpxchg128_local(ptr, o, n) \ |
| 333 | + __arch_cmpxchg128((ptr), (o), (n), "") |
| 334 | + |
| 335 | +#endif /* CONFIG_64BIT && CONFIG_RISCV_ISA_ZACAS */ |
| 336 | + |
299 | 337 | #ifdef CONFIG_RISCV_ISA_ZAWRS
|
300 | 338 | /*
|
301 | 339 | * Despite wrs.nto being "WRS-with-no-timeout", in the absence of changes to
|
|
0 commit comments