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.
> 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:
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.
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