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