Some registers are explicitly not supported for use with inline assembly:
x86 k0 This is a constant zero register which can't be modified.
Why can't the zero registers be read from?
It doesn't make sense to use a zero register as an input or output.
You are of course free to use the zero register inside your asm code.
So should that RFC text be clarified to state something more precise than "Some registers are explicitly not supported for use with inline assembly"?
As you say that we are "free to use the zero register".
OK I will clarify the text.
@Jake Goulding they can be used in inline assembly
but the content of those registers is always zero
so setting such registers as inputs in an
asm!("...", in k0(foo)) expression is pointless, since
foo won't be written to the
the same applies to using them as outputs, such the content of the register after an inline assembly expression gets written to a Rust variable, since that just means that the variable will always be zeroed
Yes, that’s why I’m pointing this out. The text of the RFC says that those registers may not be used and now multiple people are trying to correct me and say they can be used. I think @Amanieu understands the issue and is already going to clarify the mistake in the RFC.
The text does not say that they may not be used as input or output arguments, just that they may not be used at all.
Ah gotcha, yes, the text should be specific about using them in input and output arguments
This is why I started this topic with the direct quote.
@Jake Goulding I was confused by your proposed wording:
"Some registers are explicitly not supported for use with inline assembly"?
But your last suggestion makes sense (e.g. "Some registers are explicitly not supported for use as input or output arguments" or something like that)
Like, in RISC-V, if you want to implement a register to register copy (like an
mov) the simplest way would be something like and
add of the source register with
r0 (which is always zero) to the destination. So it is critically important that these "always zero" registers can be used within inline assembly.
I have not proposed any alternate wording. The part you cite as confusing is from the RFC
Again, quoted at the beginning of the topic and then later with more bolding.
I misread your second quote
I thought the bolding was a proposed change
The good thing here is that it seems we all agree the original phrasing was suboptimal.
so setting such registers as inputs in an
asm!("...", in k0(foo))expression is pointless, since
foowon't be written to the
I feel like I remember a few idioms in riscv that write to the 0 register and that make sense. Or maybe it was some other arch
IIRC it was instructions that may write to multiple outputs and when you specify one of the outputs to be 0, you get some simplified instruction (same encoding)
It seems like in that case, you still wouldn't use it as an input register. As best I can tell from your description, that would mean that you've already done the operation with multiple outputs outside the
asm! block, then are trying to move one of the outputs into the zero register and call some more assembly.
As mentioned above, you should be able to use the zero registers inside the
asm! block, so you could write
multioutput_op input1, input2, output1, $zero_reg;
yeah, just using
x0 directly in assembly makes more sense.
I remember also that
ld IMM is really encoded as
add x0, IMM IIRC. But again, just use
LLVM could pass in
x0 regardless for your "reg" constraint for
in variable if it knows variable is
0 too, but that’s transparent… or could it… nah, because you can modify the registers…
GCC uses a separate constraint code for the zero register, which allows you to specify "zr" as the constraint code. This means: select the zero register if you can (the input value is 0) otherwise use a normal register.
However LLVM doesn't support multiple constraints (it will always pick the most generic) so it will always select a normal register even if the input value is 0.
@nagisa I think you might be referring to RISC-V's
jal instruction with
x0 as the output register to discard the return address ?
cc @rkruppe - they might now
Disallowing zero registers in inputs/outputs seems to me to at least be the conservative choice. We can always allow that later if someone finds a good use for it, but I can't think of any reason why using input/outputs with them would be better than just writing them in the text literal for the assembly
For RISC-V it would be interesting to maybe specify whether the assembly literal supports pseudo-instructions like
j or not - I don't see any reasons why not, all backends should support them anyways.