On 05/01/2024 19:46, Segher Boessenkool wrote:
On Fri, Jan 05, 2024 at 05:30:51PM +0100, David Brown via Gcc-help wrote:
However, when I use just "asm ("" : "+X" (x));", I get an error message
"error: inconsistent operand constraints in an 'asm'". I have no idea
why this is an issue.
The C constraint means "Any operand whatsoever is allowed." Here you
are saying to use it both as input and as output, and GCC does not know
how to reload wherever it chose to put it.
It doesn't need to reload it - the "+" says it will be read, then
possibly changed and returned in the same place. It is geared towards
inline assembly that modifies something - you'd use it for the "x" in
assembly doing "x += a;", unlike for "x = a + b;". No reloads are
needed because the same register or memory address is used for input and
output.
Using "X" for outputs is strange already, fwiw, but tieing it to an
input is, hrm, let's call it "creative" :-)
Sure, this is a little "creative". After all, the assembly template
itself is intentionally blank. It is similar in principal to the
commonly used asm("" ::: "memory") barrier. It is an example of fully
portable assembly!
I'd imagine that the "X" operand doesn't see much use in real inline
assembly
It is used rather often. But usually for inputs, and (as you found out)
trying to use if for an input and for an output at the same time does
not work reliably.
"+" really creates two operands, and ties them together. Writing
asm("oink" : "+X"(bla));
is shorthand for
asm("oink" : "=X"(bla) : "0"(bla));
I don't know if these are /exactly/ the same, but they are certainly
similar.
I can't see any reason for there to be a special issue with "X" here. I
have not seen any complications with "g", meaning "general-purpose
register or memory". But sometimes data can be in a register that is
not general-purpose - such as a floating point register, or a SIMD
register - and then I'd rather not have extra instructions added to
force it to fit a "g" operand.