Request for discussion: Rewrite of inline assembler docs

dw limegreensocks@yahoo.com
Wed Mar 26 07:31:00 GMT 2014


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



More information about the Gcc mailing list