But when I try to compile I'm triggering an assertion:
$ rustc test.rs
rustc: /home/gabriel/projs/rust/src/llvm/lib/IR/InlineAsm.cpp:47: llvm::InlineAsm::InlineAsm(llvm::PointerType*, const string&, const string&, bool, bool, llvm::InlineAsm::AsmDialect): Assertion `Verify(getFunctionType(), constraints) && "Function type not legal for constraints!"' failed.
Aborted (core dumped)
From what I can tell from looking at the assertion my constraint isn't written correctly. I've tried a few different variations but I'm not sure what I need to fix. I'm compiling rust in debug mode now, but while I'm waiting I thought I'd ask on the forum to see if anyone has suggestions that might help solve the problem.
The x variable is to give a pointer into the stack as a comparison/validation of read_sp, e.g. playpen prints out something like:
SP: 0x7fff03079330
&x: 0x7fff03079394
This is using LLVM's support for naming specific registers in constraints, so LLVM is reading the value of sp from the sp register (automatically extended to the appropriate rsp/esp/... version). That said, the explicit mov version gives essentially the same behaviour.
The number in $0 variables refers to the position in the parameter list, so "=r"(sp) is the 0th parameter and hence the compiler will replace $0 with whatever register it chooses to use for sp.
Thanks this is a very helpful explanation. I saw syntax in gcc inline asm documentation for how to declare a variable that takes it's value from a register, but I didn't know how to translate to convert it to work for rust. It looks like your code shows how to do this and it would avoid the extra mov instruction.
As a related question I'm curious as to my my original asm statement caused the compiler to crash. Since the mov instruction can work with memory or a register would it ever be valid to let the compiler pick whatever it wants (and is there syntax for that). Or does the constraint need to explicitly specify that the variable in a register or memory (depending on the choice).