Stream: project-inline-asm

Topic: Shorthand notation for operand names


Amanieu (Dec 13 2019 at 15:07, on Zulip):

In the current asm! proposal, you can name operands the same way you can with format strings:

asm!("mov {foo}, {bar}", foo = lateout(reg) foo, bar = in(reg) bar);
Amanieu (Dec 13 2019 at 15:08, on Zulip):

Note the repetition here: foo and bar each occur 3 times in the code.

Amanieu (Dec 13 2019 at 15:09, on Zulip):

There is an RFC to improve this for format strings (https://github.com/rust-lang/rfcs/pull/2795):

let person = "Charlie";
print!("Hello, {person}!");    // implicit named argument `person`
Amanieu (Dec 13 2019 at 15:10, on Zulip):

But this won't work for us since we need additional information apart from just the variable name (in/out & register class).

mark-i-m (Dec 13 2019 at 15:37, on Zulip):

Just a thought: why not abandon positional arguments altogether? That is, the following would not only be legal, but _required_:

mark-i-m (Dec 13 2019 at 15:38, on Zulip):
asm!("mov {foo}, {bar}", lateout(reg) foo, in(reg) bar);
mark-i-m (Dec 13 2019 at 15:40, on Zulip):

I guess one could still use {0} specifiers if they really wanted positional args... but it's my experience that positional arguments are a bit of a pain in longer asm fragments because anytime you insert or remove an argument from the string, you have to count to the right place in the argument list and add or remove the right one...

Amanieu (Dec 13 2019 at 16:05, on Zulip):

Note that in my example, foo and bar are also variable, which is why the same name is used for the operand name and the value.

Amanieu (Dec 13 2019 at 16:06, on Zulip):

However asm operands can be arbitrary expressions:

asm!("mov {foo}, {bar}", foo = lateout(reg) *some_func().val, bar = in(reg) 5i32);
mark-i-m (Dec 13 2019 at 16:20, on Zulip):

Hmm... forgot about that... I don't tend to write asm fragments like that

mark-i-m (Dec 13 2019 at 16:20, on Zulip):

I'm curious how often others do?

Amanieu (Dec 13 2019 at 16:32, on Zulip):

Here's an example from my code:

    asm!(
        asm_interruptible_syscall!()
        : "=&r" (interrupted)
          "={x0}" (result)
        : "*m" (ctx.interrupt_flag)
          "{x7}" (nr as u64)
          "{x8}" (NR_TANGO_COMPAT)
          "{x13}" (ctx.sp as u64)
          "{x15}" (ctx.pc as u64)
        : "x7", "memory"
        : "volatile"
    );
Josh Triplett (Dec 15 2019 at 17:01, on Zulip):

Another issue that makes this harder for us: you can repeat a name, if you need it to appear in more than one register. For instance, consider something like in(reg) foo, inout(reg) foo, which needs to supply a register containing foo and another register containing foo that you can write to to set the outgoing value of foo. That would make {foo} ambiguous.

Amanieu (Dec 15 2019 at 17:47, on Zulip):

I'm considering not adding any shorthand notation for now. We can leave this as a future extension.

Josh Triplett (Dec 15 2019 at 17:56, on Zulip):

That sounds reasonable. We can develop a shorthand in the future, after we've had some more experience with the syntax.

Last update: Apr 05 2020 at 01:15UTC