dw <[email protected]> writes:
> On 3/25/2014 4:20 AM, Richard Sandiford wrote:
>> dw <[email protected]> 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