Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I didn't follow up the stabilization process very closely, but I believe you're wrong. What you're describing is what used to be asm! and is now llvm_asm!. The current stable asm! syntax actually parses its own assembly instead of passing it through to the backend unchanged. This was done explicitly to allow for non-llvm backends to work, and for alternative front-ends to be able to be compatible. I saw multiple statements on this thread about alternative compilers or backends causing trouble here, and that's just not the case given the design was delayed for ages until those issues could be addressed.

Given that not all platforms that are supported by rust have currently support for asm!, I believe your last paragraph does still apply.

https://rust-lang.github.io/rfcs/2873-inline-asm.html



This sentence from the Reference is important:

  > The exact assembly code syntax is target-specific and opaque to the compiler
  > except for the way operands are substituted into the template string to form
  > the code passed to the assembler.
You can verify that rustc doesn't validate the contents of asm!() by telling it to emit the raw LLVM IR:

  % cat bogus.rs
  #![no_std]
  pub unsafe fn bogus_fn() {
   core::arch::asm!(".bogus");
   core::arch::asm!("bogus");
  }
  % rustc --crate-type=lib -C panic=abort --emit=llvm-ir -o bogus.ll bogus.rs
  % cat bogus.ll
  [...]
  ; bogus::bogus_fn
  ; Function Attrs: nounwind
  define void @_ZN5bogus8bogus_fn17h0e38c0ae539c227fE() unnamed_addr #0 {
  start:
    call void asm sideeffect alignstack ".bogus", "~{cc},~{memory}"(), !srcloc !2
    call void asm sideeffect alignstack "bogus", "~{cc},~{memory}"(), !srcloc !3
    ret void
  }
That IR is going to get passed to llvm-as and possibly onward to an external assembler, which is where the actual validation of instruction mnemonics and assembler directives happens.

---

The difference between llvm_asm!() and asm!() is in the syntax of the stuff outside of the instructions/directives -- LLVM's "~{cc},~{memory}" is what llvm_asm!() accepts more-or-less directly, and asm!() generates from backend-independent syntax.

I have an example on my blog of calling Linux syscalls via inline assembly in C, LLVM IR, and Rust. Reading it might help clarify the boundary: https://john-millikin.com/unix-syscalls#inline-assembly




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: