riscv-llvm
riscv-llvm copied to clipboard
Implement and test support for all RISC-V inline asm constraints
The present inline asm constraints implementation incompleteness seems to be contributing to a confusing situation. For instance, here's my implementation of a UART in terms of a Linux-compatible system call, in D (LDC LLVM inline assembly):
__asm("ecall", "{x10},{x11},{x12},{x17},~{x10}", 1, str.ptr, str.length, 64);
You pass the arguments in registers a0-a2, and specify the system call 64 in a7. a0 is overwritten with the result, which I don't use, so I just treat it as a clobber. The obvious improvement would be to use the ABI register names directly. Changing just one of the input regs to use the ABI name:
__asm("ecall", "{a0},{x11},{x12},{x17},~{x10}", 1, str.ptr, str.length, 64);
error: couldn't allocate input reg for constraint '{a0}'
So it seems that the ABI names aren't supported, right? But changing it in the clobber works:
__asm("ecall", "{x10},{x11},{x12},{x17},~{a0}", 1, str.ptr, str.length, 64);
Trying to use the result even with the canonical register names doesn't seem to work either, so maybe this is my fault, or LDC's?
int r = __asm!int("ecall", "={x10},{x11},{x12},{x17}", 1, str.ptr, str.length, 64);
Error: __asm constraint argument is invalid
I'd like to express my interest in this bug being fixed, as it is currently causing Clang to fault when attempting to compile code from musl-riscv libc. The implementation of atomic helper functions in musl-riscv heavily uses these constraints, particularly J and A: https://github.com/lluixhi/musl-riscv/blob/master/arch/riscv64/atomic_a.h .
All of the described problems now work properly. The issue can be closed.