Patch to faq.html for invalid asms that clobber input operands, such as in linux-2.0.35

Hans-Peter Nilsson hans-peter.nilsson@axis.com
Sun Nov 1 19:11:00 GMT 1998


Since nobody RTFM anyway (...), maybe adding a FAQ entry will
have a greater impact.  We've already seen aggravated debate on
what's right for asms (some time ago).
 Now when code is "suddenly" rendered invalid, we've seen the
prelude to the coming storm when this is released somehow.
(Some people watching the barometer are CC:ed as "sufficiently
interested", sorry if not).

Identified assumptions in the FAQ entry patch proposed below:

* My recent extend.texi patch will be accepted ("now documented
  in the manual")
* I identified the right linux 2.0.35 source from browsing
  patches at linuxhq.com (still running 2.0.30 here)
* linux 2.0.35 is important enough to mention as problematic source
* The patch on
  <URL: http://www.suse.de/~florian/kernel+egcs.html > has not
  suddenly been updated to remedy the invalid-clobber problem
  (That is, I checked it, and there was no way it could address
  these problems, so I removed the "(all?)" below, close to the
  reference.)
* That I correctly remember and deduced the main political and
  technical reasons for flagging clobbered inputs as invalid and
  not just scribbled down random ravings 8-)
  (Sorry, I did not re-read any applicable mailing list
  messages; some hopefully unimportant details may be lost.) 
* This issue has not been addressed anywhere else to the extent
  that this entry would be redundant and obsolete (?... didn't
  think so).

Index: faq.html
===================================================================
RCS file: /egcs/carton/cvsfiles/wwwdocs/htdocs/faq.html,v
retrieving revision 1.69
diff -p -c -r1.69 faq.html
*** faq.html.old	1998/10/31 07:37:40	1.69
--- faq.html	1998/11/02 02:13:11
***************
*** 15,20 ****
--- 15,21 ----
    <li><a href="#fortran">Problems building the Fortran compiler</a>
    <li><a href="#mips">Problems building on MIPS platforms</a>
    <li><a href="#x86eh">Problems with exception handling on x86 platforms</a>
+   <li><a href="#asmclobber">Problems with <tt>Invalid `asm' statement</tt>s</a>
    <li><a href="#hpcompare">Bootstrap comparison failures on HPs</a>
    <li><a href="#makebugs">Bootstrap loops rebuilding cc1 over and over</a>
    <li><a href="#rpath">Dynamic linker is unable to find GCC libraries</a>
*************** Or, you can try a
*** 314,319 ****
--- 315,394 ----
  and may not work (or even build).  Use it at your own risk.
  
  <hr>
+ <h2><a name="asmclobber">Problems with invalid `asm' statements</a></h2>
+ <p>Previous releases of gcc did not detect as invalid a clobber specifier
+ that clobbered an input operands.  Instead, it could spuriously and
+ undetected generate incorrect code for certain non-obvious cases of source
+ code.  Even more unfortunate, the manual did not explicitly say that it
+ was invalid to specify clobber registers that were destined to overlap
+ input operands.
+ 
+ <p>For the general case, there is no way to tell whether a specified
+ clobber is <i>intended</i> to overlap with a specific input operand or is
+ a program error, where the choice of actual register for input operands
+ failed to <i>avoid</i> the clobbered register.  Such unavoidable overlap
+ is now (with current egcs sources in CVS) detected, and flagged as an
+ error rather than accepted.  An error message is given, such as:
+ <pre>
+ foo.c: In function `foo':
+ foo.c:7: Invalid `asm' statement:
+ foo.c:7: fixed or forbidden register 0 (ax) was spilled for class AREG.
+ </pre>
+ Unfortunately, a lot of existing software, for example the
+ <a href="#linuxkernel">linux kernel</a> version 2.0.35 for the Intel x86,
+ has these constructs.
+ 
+ <p>How to write asm constructs with input operands that are modified by
+ the construct but not actually used as output operands, is now documented
+ in the manual.  To write an asm which modifies an input operand but does
+ not output anything usable, specify that operand as an <b>output
+ operand</b> outputting to an <b>unused dummy variable</b>.
+ 
+ <p>In the following example for the x86 architecture (taken from the linux
+ 2.0.35 kernel -- <tt>include/asm-i386/delay.h</tt>), the register-class
+ constraint <tt>"a"</tt> denotes a register class containing the single
+ register <tt>"ax"</tt> (aka. <tt>"eax"</tt>).  It is therefore invalid
+ to clobber <tt>"ax"</tt>; this operand has to be specified as an output
+ as well as an input.  The following code is therefore <b>invalid</b>:
+ <pre>
+ extern __inline__ void
+ __delay (int loops)
+ {
+   __asm__ __volatile__
+     (".align 2,0x90\n1:\tdecl %0\n\tjns 1b"
+      : /* no outputs */
+      : "a" (loops)
+      : "ax");
+ }
+ </pre>
+ It could be argued that since the register class for <tt>"a"</tt> contains
+ only a single register, this could be detected as an "obvious" intended
+ clobber of the input operand.  While that is feasible, it opens up for
+ further "obvious" cases, where the level of obviousness changes from
+ person to person.  As there is a correct way to write such asm constructs,
+ this obviousness-detection is not needed other than for reasons of
+ compatibility with an existing code-base, and that code base can be
+ corrected.
+ <p>
+ The corrected and clobber-less version, is <b>valid</b> for egcs of
+ current CVS, as well as for previous versions of gcc:
+ <pre>
+ extern __inline__ void
+ __delay (int loops)
+ {
+   int dummy;
+ 
+   __asm__ __volatile__
+     (".align 2,0x90\n1:\tdecl %0\n\tjns 1b"
+      : "=a" (dummy)
+      : "0" (loops));
+ }
+ </pre>
+ Note that the asm construct now has an output operand, but it is unused.
+ Normally asm constructs with only unused output operands may be removed by
+ gcc, unless marked <tt>volatile</tt> as above.
+ 
+ <hr>
  <h2><a name="hpcompare">Bootstrap comparison failures on HPs</a></h2>
  <p>If you bootstrap the compiler on hpux10 using the HP assembler instead of
  gas, every file will fail the comparison test.
*************** with gcc-2.7.2.  They use certain asm co
*** 434,440 ****
  (by accident) happen to work with gcc-2.7.2.  If you insist on building
  2.0.xx kernels with egcs, you may be interested in this 
  <a href=" http://www.suse.de/~florian/kernel+egcs.html ">patch</a> which
! fixes some (all?) of the asm problems.
  
  <p>If you installed a recent binutils/gas snapshot on your Linux system,
  you may not be able to build the kernel because objdump does not understand
--- 509,516 ----
  (by accident) happen to work with gcc-2.7.2.  If you insist on building
  2.0.xx kernels with egcs, you may be interested in this 
  <a href=" http://www.suse.de/~florian/kernel+egcs.html ">patch</a> which
! fixes some of the asm problems.  You will also want to change asm constructs
! to <a href="#asmclobber">avoid clobbering their input operands</a>.
  
  <p>If you installed a recent binutils/gas snapshot on your Linux system,
  you may not be able to build the kernel because objdump does not understand

brgds, H-P
-- 
Hans-Peter Nilsson, Axis Communications AB, S - 223 70 LUND, SWEDEN
Hans-Peter.Nilsson@axis.se | Tel +46 462701867,2701800
Fax +46 46136130 | RFC 1855 compliance implemented; report loss of brain.



More information about the Gcc-patches mailing list