This is the mail archive of the
binutils@sourceware.cygnus.com
mailing list for the binutils project.
Re: GAS problems
- To: Horst von Brand <vonbrand at sleipnir dot valparaiso dot cl>
- Subject: Re: GAS problems
- From: Alan Modra <alan at SPRI dot Levels dot UniSA dot Edu dot Au>
- Date: Mon, 18 Oct 1999 13:15:52 +0930 (CST)
- cc: binutils at sourceware dot cygnus dot com
On Sun, 17 Oct 1999, Horst von Brand wrote:
> The lcc C compiler on ia32 generates "fxxxp %st(1),%st" instructions to
> handle floating point operations. This is handled wrong by H.J.Lu's
> binutils-2.9.5.0.16. Note that now it translates "fsubp %st(1),%st" into
> "fsubp %st,%st(1)", which does something very different. Also, the
> instructions are legal AFAIK (they used to work before), so either no
> warning is needed or you could use f.ex. "fsubrp %st,%st(1)" if there is a
> penalty of some sort. In any case, I would prefer you left them alone.
These floating point operations are a real pain, but in this case lcc is
doing something wrong. There is no such x86 instruction. What should
"fsubp %st(1),%st" do? I'd imagine it should do st <- st - st(1), then
pop off the result, which is a bit silly. Note that older binutils
silently did the same translation we now do (and older gcc emitted this
wrong instruction too)
FYI, here's a comment I added to binutils/include/opcode/i386.h, just to
make you aware of a horrible kludge.
/* The UnixWare assembler, and probably other AT&T derived ix86 Unix
assemblers, generate floating point instructions with reversed
source and destination registers in certain cases. Unfortunately,
gcc and possibly many other programs use this reversed syntax, so
we're stuck with it.
eg. `fsub %st(3),%st' results in st <- st - st(3) as expected, but
`fsub %st,%st(3)' results in st(3) <- st - st(3), rather than
the expected st(3) <- st(3) - st !
This happens with all the non-commutative arithmetic floating point
operations with two register operands, where the source register is
%st, and destination register is %st(i). Look for FloatDR below. */
#ifndef UNIXWARE_COMPAT
/* Set non-zero for broken, compatible instructions. Set to zero for
non-broken opcodes at your peril. gcc generates UnixWare
compatible instructions. */
#define UNIXWARE_COMPAT 1
#endif
I would love to get rid of this stupidity, but that needs a
synchronised update of both gcc and binutils.