Hi Andrea, On 27/06/2024 13:06, Andrea Parri wrote:
-#define __arch_cmpxchg(lr_sfx, sc_sfx, prepend, append, r, p, co, o, n) \ +#define __arch_cmpxchg(lr_sfx, sc_cas_sfx, prepend, append, r, p, co, o, n) \ ({ \ + __label__ zacas, end; \ register unsigned int __rc; \ \ + if (IS_ENABLED(CONFIG_RISCV_ISA_ZACAS)) { \ + asm goto(ALTERNATIVE("nop", "j %[zacas]", 0, \ + RISCV_ISA_EXT_ZACAS, 1) \ + : : : : zacas); \ + } \ + \ __asm__ __volatile__ ( \ prepend \ "0: lr" lr_sfx " %0, %2\n" \ " bne %0, %z3, 1f\n" \ - " sc" sc_sfx " %1, %z4, %2\n" \ + " sc" sc_cas_sfx " %1, %z4, %2\n" \ " bnez %1, 0b\n" \ append \ "1:\n" \ : "=&r" (r), "=&r" (__rc), "+A" (*(p)) \ : "rJ" (co o), "rJ" (n) \ : "memory"); \ + goto end; \ + \ +zacas: \ + if (IS_ENABLED(CONFIG_RISCV_ISA_ZACAS)) { \ + __asm__ __volatile__ ( \ + prepend \ + " amocas" sc_cas_sfx " %0, %z2, %1\n" \ + append \ + : "+&r" (r), "+A" (*(p)) \ + : "rJ" (n) \ + : "memory"); \ + } \Is this second IS_ENABLED(CONFIG_RISCV_ISA_ZACAS) check actually needed? (just wondering - no real objection)
To me yes, otherwise a toolchain without zacas support would fail to assemble the amocas instruction.
+end:; \Why the semicolon?
That fixes a clang warning reported by Nathan here: https://lore.kernel.org/linux-riscv/20240528193110.GA2196855@thelio-3990X/
})#define _arch_cmpxchg(ptr, old, new, sc_sfx, prepend, append) \@@ -156,7 +177,7 @@ __typeof__(ptr) __ptr = (ptr); \ __typeof__(*(__ptr)) __old = (old); \ __typeof__(*(__ptr)) __new = (new); \ - __typeof__(*(__ptr)) __ret; \ + __typeof__(*(__ptr)) __ret = (old); \This is because the compiler doesn't realize __ret is actually initialized, right? IAC, seems a bit unexpected to initialize with (old) (which indicates SUCCESS of the CMPXCHG operation); how about using (new) for the initialization of __ret instead? would (new) still work for you?
But amocas rd register must contain the expected old value in order to actually work right?
Andrea _______________________________________________ linux-riscv mailing list linux-riscv@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/linux-riscv