correct the operand specifiers in the riscv64 CAS routines

The operand sepcifiers in a_cas and a_cas_p for riscv64 were incorrect:
there's a backwards branch in the routine, so despite tmp being written
at the end of the assembly fragment it cannot be allocated in one of the
input registers because the input values may be needed for another trip
around the loop.

For code that follows the guaranteed forward progress requirements, the
backwards branch is rarely taken: SiFive's hardware only fails a store
conditional on execptional cases (ie, instruction cache misses inside
the loop), and until recently a bug in QEMU allowed back-to-back
store conditionals to succeed.  The bug has been fixed in the latest
QEMU release, but it turns out that the fix caused this latent bug in
musl to manifest.
This commit is contained in:
Palmer Dabbelt 2019-09-24 20:30:15 -07:00 committed by Rich Felker
parent f5eee489f7
commit 7d5c5706a0
1 changed files with 2 additions and 2 deletions

View File

@ -14,7 +14,7 @@ static inline int a_cas(volatile int *p, int t, int s)
" sc.w.aqrl %1, %4, (%2)\n" " sc.w.aqrl %1, %4, (%2)\n"
" bnez %1, 1b\n" " bnez %1, 1b\n"
"1:" "1:"
: "=&r"(old), "=r"(tmp) : "=&r"(old), "=&r"(tmp)
: "r"(p), "r"(t), "r"(s) : "r"(p), "r"(t), "r"(s)
: "memory"); : "memory");
return old; return old;
@ -31,7 +31,7 @@ static inline void *a_cas_p(volatile void *p, void *t, void *s)
" sc.d.aqrl %1, %4, (%2)\n" " sc.d.aqrl %1, %4, (%2)\n"
" bnez %1, 1b\n" " bnez %1, 1b\n"
"1:" "1:"
: "=&r"(old), "=r"(tmp) : "=&r"(old), "=&r"(tmp)
: "r"(p), "r"(t), "r"(s) : "r"(p), "r"(t), "r"(s)
: "memory"); : "memory");
return old; return old;