dw <limegreenso...@yahoo.com> writes: > On 2/27/2014 4:11 AM, Richard Sandiford wrote: >> Andrew Haley <a...@redhat.com> 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 <limegreenso...@yahoo.com> 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