Something's been bugging me about this syntax and I finally figured out what it is. You can have an operand that's a sym, an imm, or a register. Only registers accept direction specifications. But with a register, you write the direction first and the register (which will often be just reg, which looks like a keyword from the same class as imm and sym) second. This is likely to be a source of confusion. For instance, it confused me into not being able to figure out how to write a sym operand for about five minutes while I was writing comment #43 on this thread, because I was looking at the wrong part of the BNF.
Can we please swap the positions of dir_spec and reg_spec in reg_operand? Making no other changes, i.e.
reg_operand := reg_spec "(" dir_spec ")" operand_expr
Rewriting some of the examples from the proposal in this form:
asm!("mov {}, 5", reg(out) x);
asm!("
mov {0}, {1}
add {0}, {2}
", reg(out) o, reg(in) i, imm 5);
asm!("
mov {o}, {i}
add {o}, {number}
", o = reg(out) o, i = reg(in) i, number = imm 5);
asm!("add {0}, {number}", reg(inout) x, number = imm 5);
asm!("out 0x64, {}", "eax"(in) cmd);
asm!(
"cpuid",
"eax"(in) 4, "ecx"(in) 0,
"ebx"(lateout) ebx, "ecx"(lateout) ecx,
"eax"(lateout) _, "edx"(lateout) _
);