This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Request for discussion: Rewrite of inline assembler docs



On 3/25/2014 4:20 AM, Richard Sandiford wrote:
dw <limegreensocks@yahoo.com> writes:
    asm ("" : "=m" (*x), "=r" (y));

you have to assume that the address in %0 might use the same register as %1
Ok, now I'm getting there.  It helps that I've compiled some examples
and can see what is happening.  This one is subtle.  I'm going to have
to go back and review my code to see if I've ever done this.

So, the existing text (which only talks about overlaps with input
parameters) reads:

"Unless an output operand has the '&' constraint modifier (see
Modifiers), GCC may allocate it in the same register as an unrelated
input operand, on the assumption that the assembler code will consume
its inputs before producing outputs. This assumption may be false if the
assembler code actually consists of more than one instruction. In this
case, use '&' for each output operand that must not overlap an input."

I'm thinking about adding something like this after it:

"The same problem can occur if one of the output parameters allows a
register constraint and contains an address.  In this case, GCC may use
maybe "...and another output parameter contains..."?  Filtering that
through:

the same register for this parameter as it does for other output
parameters that allow a memory constraint.  This can produce
inconsistent results if the register address is updated before updating
the memory address.  Combining the '&' constraint with the register
constraint prevents this overlap and resolves the inconsistency."

That's as clear as I can come up with.  Better?
how about:

The same problem can occur if one output parameter @var{a} allows a register
constraint and another output parameter @var{b} allows a memory constraint.
The memory address in @var{b} may contain registers and GCC treats those
registers as inputs to the asm.  As above, GCC assumes that such input
registers are consumed before any outputs are written.  If in fact the
asm writes to @var{a} before @var{b}, it may inadvertently change the
address used for @var{b}.  Combining the '&' constraint with the register
constraint prevents this overlap and ensures that @var{a} and @var{b}
can be written in either order.

Not sure that's much good though, sorry.

That helps alot.  Of course I had to fiddle with it just a bit more...

While adding the '&' ensures that modifying @var{a} will not affect what address is referenced by @var{b}, I worry that someone might assume by implication that *omitting* it means that b will always follow a. But I don't believe that's guaranteed. It seems like it might, or it might not depending on the "whims" of the optimizer, with tiny changes in "unrelated" code swinging things back and forth.

Also, I believe the problem is slightly more limited than the language above (both yours and mine) implies.

These points plus some minor languages changes gives me:

The same problem can occur if one output parameter (@var{a}) allows a register constraint, is updating the parameter value, and references an address while another output parameter (@var{b}) allows a memory constraint. The code generated by GCC to access the memory address in @var{b} can contain registers which @emph{might} be shared by @var{a}, and GCC considers those registers to be inputs to the asm. As above, GCC assumes that such input registers are consumed before any outputs are written. This assumption may result in incorrect behavior if the asm writes to @var{a} before using @var{b}. Combining the '@code{&}' constraint with the register constraint ensures that modifying @var{a} will not affect what address is referenced by @var{b}. Omitting the '@code{&}' constraint means that the location of @var{b} will be undefined if @var{a} is modified before using @var{b}.

Done?

Thanks,
Richard


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]