-
Notifications
You must be signed in to change notification settings - Fork 13.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Inline assembly #5317
Inline assembly #5317
Conversation
This is awesome. |
This is actually quite useful for stack switching. |
pub fn InlineAsmCall(cx: block, asm: *c_char, cons: *c_char, | ||
dia: AsmDialect) -> ValueRef { | ||
unsafe { | ||
count_insn(cx, "inlineasm"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not a smart Compiler or Rust hacker but I'm too curious to let this go. Is count_insn
effectively a nop here? If not, how is the space required for the generated assembly calculated without count_insn
being passed asm
?
llfty
seems to be a function stub for the inline assembly and v
should be the bytevector returned by LLVM's assembler. The fact that the majority of this patch is readable to a noob like myself is great fun. And feel free to ignore, I know you guys have lots more important things to do. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe count_insn
is just for some stats. Running rustc -Z count-llvm-insns
will give you some counts of where LLVM insns originate.
Yes, llfty
is the "type" of the inline assembly. Right now it's just a void return type with no input args since I haven't actually added the things necessary to make it take input and output operands.
So it can now parse it more or less like gcc/clang (though it doesn't actually do anything with input/output operands yet): asm!( assembler template // literal string
: output operands // optional, format: "constraint1"(expr1), "constraint2"(expr2), etc
: input operands // optional, format: "constraint1"(expr1), "constraint2"(expr2), etc
: clobbers // optional, format: "%eax", "%ebx", "memory", etc
: options // optional, comma separated strings
); The options bit is not something in gcc or clang. It's just a way to specify some extra keywords to LLVM about the assembly. Right now the only ones are For
|
```Rust #[cfg(target_os = "macos")] fn helloworld() { unsafe { asm!(".pushsection __RODATA, __rodata msg: .asciz \"Hello World!\" .popsection movq msg@GOTPCREL(%rip), %rdi call _puts"); } } #[cfg(target_os = "linux")] fn helloworld() { unsafe { asm!(".pushsection .rodata msg: .asciz \"Hello World!\" .popsection movq msg@GOTPCREL(%rip), %rdi call puts"); } } fn main() { helloworld(); } ``` ``` % rustc foo.rs % ./foo Hello World! ```
Continuation of #5317. Actually use operands properly now, including any number of output operands. Which means you can do things like call printf: ```Rust fn main() { unsafe { do str::as_c_str(~"The answer is %d.\n") |c| { let a = 42; asm!("mov $0, %rdi\n\t\ mov $1, %rsi\n\t\ xorl %eax, %eax\n\t\ call _printf" : : "r"(c), "r"(a) : "rdi", "rsi", "eax" : "volatile","alignstack" ); } } } ``` ``` % rustc foo.rs % ./foo The answer is 42. ``` Or just add 2 numbers: ```Rust fn add(a: int, b: int) -> int { let mut c = 0; unsafe { asm!("add $2, $0" : "=r"(c) : "0"(a), "r"(b) ); } c } fn main() { io::println(fmt!("%d", add(1, 2))); } ``` ``` % rustc foo.rs % ./foo 3 ``` Multiple outputs! ```Rust fn addsub(a: int, b: int) -> (int, int) { let mut c = 0; let mut d = 0; unsafe { asm!("add $4, $0\n\t\ sub $4, $1" : "=r"(c), "=r"(d) : "0"(a), "1"(a), "r"(b) ); } (c, d) } fn main() { io::println(fmt!("%?", addsub(5, 1))); } ``` ``` % rustc foo.rs % ./foo (6, 4) ``` This also classifies inline asm as RvalueStmtExpr instead of the somewhat arbitrary kind I made it initially. There are a few XXX's regarding what to do in the liveness and move passes.
Rustup to rust-lang#69076 changelog: none
Issue #98.