dw <[email protected]> writes:
> On 2/27/2014 4:11 AM, Richard Sandiford wrote:
>> Andrew Haley <[email protected]> writes:
>>> Over the years there has been a great deal of traffic on these lists
>>> caused by misunderstandings of GCC's inline assembler. That's partly
>>> because it's inherently tricky, but the existing documentation needs
>>> to be improved.
>>>
>>> dw <[email protected]> has done a fairly thorough reworking of
>>> the documentation. I've helped a bit.
>>>
>>> Section 6.41 of the GCC manual has been rewritten. It has become:
>>>
>>> 6.41 How to Use Inline Assembly Language in C Code
>>> 6.41.1 Basic Asm - Assembler Instructions with No Operands
>>> 6.41.2 Extended Asm - Assembler Instructions with C Expression Operands
>>>
>>> We could simply post the patch to GCC-patches and have at it, but I
>>> think it's better to discuss the document here first. You can read it
>>> at
>>>
>>> http://www.LimeGreenSocks.com/gcc/Basic-Asm.html
>>> http://www.LimeGreenSocks.com/gcc/Extended-Asm.html
>>> http://www.LimeGreenSocks.com/gcc/extend04.zip (contains .texi, .patch,
>>> and affected html pages)
>>>
>>> All comments are very welcome.
>> Thanks for doing this, looks like a big improvement.
>
> Thanks, I did my best. I appreciate you taking the time to review them.
>
>> A couple of comments:
>>
>> The section on basic asms says:
>>
>> Do not expect a sequence of asm statements to remain perfectly
>> consecutive after compilation. To ensure that assembler instructions
>> maintain their order, use a single asm statement containing multiple
>> instructions. Note that GCC's optimizer can move asm statements
>> relative to other code, including across jumps.
>>
>> The "maintain their order" might be a bit misleading, since volatile asms
>> (including basic asms) must always be executed in the original order.
>> Maybe this was meaning placement/address order instead?
>
> This statement is based on this text from the existing docs:
>
> "Similarly, you can't expect a sequence of volatile |asm| instructions
> to remain perfectly consecutive. If you want consecutive output, use a
> single |asm|."
>
> I do not dispute what you are saying. I just want to confirm that the
> existing docs are incorrect before making a change. Also, see Andi's
> response re -fno-toplevel-reorder.
>
> It seems to me that recommending "single statement" is both the
> clearest, and the safest approach here. But I'm prepared to change my
> mind if there is consensus I should.
Right. I agree with that part. I just thought that the "maintain their
order" could be misunderstood as meaning execution order, whereas I think
both sentences of the original docs were talking about being "perfectly
consecutive" (which to me means "there are no other instructions inbetween").
Maybe a wordsmithed version of:
Do not expect a sequence of asm statements to remain perfectly
consecutive after compilation. If you want to stop the compiler
inserting anything into a sequence of assembler instructions,
you should put those instructions in a single asm statement. [...]
>> It might also be
>> worth mentioning that the number of instances of an asm in the output
>> may be different from the input. (Can it increase as well as decrease?
>> I'm not sure off-hand, but probably yes.)
>
> So, in the volatile section, how about something like this for decrease:
>
> "GCC does not delete a volatile |asm| if it is reachable, but may delete
> it if it can prove that control flow never reaches the location of the
> instruction."
It's not just that though. AIUI it would be OK for:
if (foo)
{
...
asm ("x");
}
else
{
...
asm ("x");
}
to become:
if (foo)
...
else
...
asm ("x");
> For increase (not quite sure where to put this yet):
>
> "Under certain circumstances, GCC may duplicate your asm code as part of
> optimization. This can lead to unexpected duplicate symbol errors
> during compilation if symbols or labels are being used. Using %= (see
> Assembler Template) may help resolve this problem."
Sounds good.
>> In the extended section:
>>
>> Unless an output operand has the '&' constraint modifier (see
>> Modifiers), GCC may allocate it in the same register as an unrelated
>> input operand, [...]
>>
>> It could also use it for addresses in other (memory) outputs.
>
> Ok. But I'm not sure this really adds anything. Having warned people
> that the register may be re-used unless '&' is used seems sufficient.
It matters where it can be reused though. If you talk about input
operands only, people might think it is OK to write asms of the form:
foo tmp,[input0]
bar [output0],tmp
frob [output1],tmp
where output0 is a register and output1 is a memory. This safely avoids
using the input operand after assigning to output0, but the address in
output1 is still live and could be changed by bar.
Thanks,
Richard