Message-ID: <002201be658c$df186fa0$b0e35982@cal012054.student.utwente.nl> From: "Derkjan de Haan" To: Subject: Re: register spilled Date: Wed, 3 Mar 1999 16:45:31 +0100 MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit X-Priority: 3 X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook Express 4.72.3155.0 X-MimeOLE: Produced By Microsoft MimeOLE V4.72.3155.0 Reply-To: pgcc AT delorie DOT com >When i compile wine www.winehq.org >I get lots of "forbidden register spilled" errors. >egcs and gcc 2.7.x works fine. Something like below ? (taken from the egcs FAQ) regards, Derkjan de Haan Problems with invalid `asm' statements Previous releases of gcc (for example, gcc-2.7.2.X) did not detect as invalid a clobber specifier that clobbered an operand. Instead, it could spuriously and silently generate incorrect code for certain non-obvious cases of source code. Even more unfortunately, the manual (Using and Porting GCC, section Extended Asm, see the bug report entry) did not explicitly say that it was invalid to specify clobber registers that were destined to overlap operands; it could arguably be interpreted that it was correct to clobber an input operand to mark it as not holding a usable value after the asm. For the general case, there is no way to tell whether a specified clobber is intended to overlap with a specific (input) operand or is a program error, where the choice of actual register for operands failed to avoid the clobbered register. Such unavoidable overlap is detected by versions egcs-2.92.18 19981104 and above, and flagged as an error rather than accepted. An error message is given, such as: 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. Unfortunately, a lot of existing software, for example the Linux kernel version 2.0.35 for the Intel x86, has constructs where input operands are marked as clobbered. The manual now describes how to write constructs with operands that are modified by the construct, but not actually used. To write an asm which modifies an input operand but does not output anything usable, specify that operand as an output operand outputting to an unused dummy variable. In the following example for the x86 architecture (taken from the Linux 2.0.35 kernel -- include/asm-i386/delay.h), the register-class constraint "a" denotes a register class containing the single register "ax" (aka. "eax"). It is therefore invalid to clobber "ax"; this operand has to be specified as an output as well as an input. The following code is therefore invalid: extern __inline__ void __delay (int loops) { __asm__ __volatile__ (".align 2,0x90\n1:\tdecl %0\n\tjns 1b" : /* no outputs */ : "a" (loops) : "ax"); } It could be argued that since the register class for "a" 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. This corrected and clobber-less version, is valid for egcs of current CVS, as well as for previous versions of gcc: extern __inline__ void __delay (int loops) { int dummy; __asm__ __volatile__ (".align 2,0x90\n1:\tdecl %0\n\tjns 1b" : "=a" (dummy) : "0" (loops)); } 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 volatile as above.