]> git.lizzy.rs Git - rust.git/commit
asm: Allow multiple template strings; interpret them as newline-separated
authorJosh Triplett <josh@joshtriplett.org>
Mon, 15 Jun 2020 06:33:55 +0000 (23:33 -0700)
committerJosh Triplett <josh@joshtriplett.org>
Mon, 15 Jun 2020 19:35:27 +0000 (12:35 -0700)
commit1078b6f9420c47fe99553d9dd8a58b232ba84b5e
treeb75a13fd2b953f6bff15c98973a44ab256261be1
parent50d6d4de67d76f03f8a8b209881a924f2d69922f
asm: Allow multiple template strings; interpret them as newline-separated

Allow the `asm!` macro to accept a series of template arguments, and
interpret them as if they were concatenated with a '\n' between them.
This allows writing an `asm!` where each line of assembly appears in a
separate template string argument.

This syntax makes it possible for rustfmt to reliably format and indent
each line of assembly, without risking changes to the inside of a
template string. It also avoids the complexity of having the user
carefully format and indent a multi-line string (including where to put
the surrounding quotes), and avoids the extra indentation and lines of a
call to `concat!`.

For example, rewriting the second example from the [blog post on the new
inline assembly
syntax](https://blog.rust-lang.org/inside-rust/2020/06/08/new-inline-asm.html)
using multiple template strings:

```rust

fn main() {
    let mut bits = [0u8; 64];
    for value in 0..=1024u64 {
        let popcnt;
        unsafe {
            asm!(
                "    popcnt {popcnt}, {v}",
                "2:",
                "    blsi rax, {v}",
                "    jz 1f",
                "    xor {v}, rax",
                "    tzcnt rax, rax",
                "    stosb",
                "    jmp 2b",
                "1:",
                v = inout(reg) value => _,
                popcnt = out(reg) popcnt,
                out("rax") _, // scratch
                inout("rdi") bits.as_mut_ptr() => _,
            );
        }
        println!("bits of {}: {:?}", value, &bits[0..popcnt]);
    }
}
```

Note that all the template strings must appear before all other
arguments; you cannot, for instance, provide a series of template
strings intermixed with the corresponding operands.

In order to get srcloc mappings right for macros that generate
multi-line string literals, create one line_span for each
line in the string literal, each pointing to the macro.

Make `rustc_parse_format::Parser::curarg` `pub`, so that we can
propagate it from one template string argument to the next.
src/librustc_builtin_macros/asm.rs
src/librustc_parse_format/lib.rs
src/test/pretty/asm.pp
src/test/pretty/asm.rs
src/test/ui/asm/parse-error.rs
src/test/ui/asm/parse-error.stderr
src/test/ui/asm/srcloc.rs
src/test/ui/asm/srcloc.stderr