Insufficient asm constraints in set_initial_registers
Currently all implementations use
"r" (®s) as an input constraint and mark a temporary register as clobbered for saving the current program counter. However, that input constraint merely says that the inline assembly reads the address, not that it also stores via it.
The solution is to use
"=m" (regs) as an output constraint, though by itself that has issues because then you get
0(reg) (possibly non-zero if
sp, though Clang doesn't do that currently, only GCC) as the expansion on RISC-V (or equivalent on other architectures) and so cannot also use an immediate offset easily, so the trick GCC recommends is to give an extra dummy argument to communicate this (both GCC and Clang are smart enough to have the same register allocated to multiple arguments when permitted by the constraints), whilst still using the
"r" one in the actual assembly body, i.e.:
:"=m" (regs) /* (dummy) output */ :"r" (®s) /* input */
and then use
%1 everywhere instead of
%0. The alternative is the big hammer that is a memory clobber.