This is the mail archive of the gas2@sourceware.cygnus.com mailing list for the gas2 project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: gcc generates invalid i386 fmulp


>hjl@lucon.org (H.J. Lu):
> > For anyone who's interested, the gas patches can be found at
> > ftp://mullet.levels.unisa.edu.au/private/teabag/gas-980407-alan.diff.gz
> > They should apply to binutils-2.9 without problems too.
> > 
> > The gcc problem (found by mikeg@weiden.de (Michael L. Galbraith)),
> > when compiling glibc2 is that gcc will generate instructions like
> > 	`fsubp %st(1),%st'
> > 
> 
> Can you show me a small test case please? It is very tricky. Here are
> the ChangeLog entries:
> [deleted]

Yes, I know it's tricky.  Basically, Unixware got their assembler
wrong, and we're stuck with an inconsistent syntax.  A test case for
fmulp is glibc-2.0.6/sysdeps/libm-ieee754/s_nextafterf.c.  I put the
preprocessed file at
ftp://mullet.levels.unisa.edu.au/private/teabag/s_nextafterf.i
Mike Galbraith may be able to give you a .i file for the fsubp case;
I didn't have the right version of glibc.

>From the start of binutils/include/opcodes/i386.h:

/* The UnixWare assembler, and possibly other ix86 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
   `fusb %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

> 
> It is very different from Intel and very confusing. But changing it
> will break many things.

I haven't diverged from the UnixWare syntax, even though I'd dearly
like to.  We just put out a warning for the cases where gcc generates
instructions **that won't assemble on UnixWare**.  Ian Taylor was kind
enough to run a number of test cases through a UnixWare assembler for
me.

Regards, Alan Modra