dw <limegreenso...@yahoo.com> writes:
> On 3/25/2014 4:20 AM, Richard Sandiford wrote:
>> dw <limegreenso...@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.

OK.

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

I think it really is general though.  In:

> 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.

I don't understand what you mean by "updating the parameter value",
but the "references an address" isn't required.  E.g. for:

int foo (int **x)
{
  int res;
  asm ("" : "=r" (res), "=m" (**x));
  return res;
}

there's nothing address-like in operand 0, but it could still end
up using the same register as the address in operand 1.

> 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}.

This part sounds good though.

Thanks,
Richard

Reply via email to