That seems like it would introduce a lot of redundancy when inputs, outputs, clobbered registers, etc. occur more than once, with all the usual problems of redundancy. Even in your example there’s already two copies of volatile.
Hmm... that is true. My intention is that every place that requires the flag (e.g. volatile) is annotated that way. In my example, if I later decided that I wanted to take out the nop
it is trivial to know that volatile
is still needed because the xor
is also annotated volatile
. Likewise, if I wanted to take out the last two instructions, it is trivially clear that volatile
is not needed any more.
Would shorter annotations help (e.g. vol
instead of volatile
)? I'm not sure what to do about this. Frankly, most of the inline assembly I have ever written is pretty short (<30 LOC per function), so I would gladdly take the redundancy hit.
I also find it confusing that your proposed syntax does not name the instruction operands in the format strings, apparently instead inferring them solely from the constraints?! Do you mean to propose that as well?
Sorry, I should have made this more clear. No, I don't want to propose this sort of inference. I was trying to propose that the format would be something roughly like this:
(INST (":" ARG_WITH_ANNOTATIONS)* (":" EXTRA_FLAGS)? ",")+
where INST
is "mov"
, ARG_WITH_ANNOTATIONS
is in reg "eax" x
, etc., and extra flags could be volatile
.
I see that my example actually is incorrect:
"xor" : inout clobber reg "eax" w : volatile
should be
"xor" : inout clobber reg "eax" w : inout clobber reg "eax" w : volatile
I do see the annoying-ness of this, though... What if we instead had per-instruction positional arguments:
let w: u32;
let x: u32;
let y: u32;
asm_x86_att! {
"mov {0}, {1}" : in reg "eax" x, out clobber reg "ebx" y;
"mov {0}, {1}" : in mem "(eab)", out clobber mem "ecx";
"nop" : volatile;
"xor {0}, {0}" : inout clobber reg "eax" w, volatile;
}
@hanna-kruppe Does that seem any better to you?