Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 16 Nov 2007 05:46:15 +1100
From:      Peter Jeremy <peterjeremy@optushome.com.au>
To:        Pete French <petefrench@ticketswitch.com>
Cc:        stable@freebsd.org, bde@freebsd.org
Subject:   Re: Float problen running i386 inary on amd64
Message-ID:  <20071115184615.GL20992@server.vk2pj.dyndns.org>
In-Reply-To: <E1IseEn-000315-Uy@dilbert.ticketswitch.com>
References:  <20071115062002.GK89746@server.vk2pj.dyndns.org> <E1IseEn-000315-Uy@dilbert.ticketswitch.com>

next in thread | previous in thread | raw e-mail | index | archive | help

--DocE+STaALJfprDB
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

I've Cc'd bde@ because this relates to the FPU initialisation - which
he is the expert on.

On Thu, Nov 15, 2007 at 12:54:29PM +0000, Pete French wrote:
>> On Fri, Nov 02, 2007 at 10:04:48PM +0000, Pete French wrote:
>> >	int
>> >	main(int argc, char *argv[])
>> >	{
>> >        	if(atof("3.2") =3D=3D atof("3.200"))
>> >                	puts("They are equal");
>> >        	else
>> >                	puts("They are NOT equal!");
>> >        	return 0;
>> >	}
>>
>> Since the program as defined above does not include any prototype for
>> atof(), its return value is assumed to be int.  The i386 code for the
>> comparison is therefore:
>
>Sorry, I didn't bother sticking the include lines in when I sent it
>to the mailing list as I assumed it would be ovious that you need
>to include the prototypes!

OK, sorry for the confusion.

>Interestingly, if you recode like this:
>
>        double x =3D atof("3.2");
>        double y =3D atof("3.200");
>        if(x =3D=3D y)
>                puts("They are equal");
>        else
>                puts("They are NOT equal!");
>
>Then the problem goes away! Glancing at the assembly code they both appear=
 to
>be doing the same thing as regards the comparison.

The underlying problem is that the amd64 FPU is initialised to 64-bit
precision mode, whilst the i386 FPU is initialised to 53-bit precision
mode (__INITIAL_FPUCW__ in amd64/include/fpu.h vs __INITIAL_NPXCW__ in
i386/include/npx.h).  It looks like the FPU is initialised during the
machine-dependent CPU initialisation and then inherited by subsequent
processes as they are fork()d.  The fix is probably to explicitly
initialise the FPU for legacy mode processes on the amd64.

A work-around would be to call fpsetprec(FP_PD) (see <machine/ieeefp.h>)
at the start of main().

--=20
Peter Jeremy
Please excuse any delays as the result of my ISP's inability to implement
an MTA that is either RFC2821-compliant or matches their claimed behaviour.

--DocE+STaALJfprDB
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.4 (FreeBSD)

iD8DBQFHPJP3/opHv/APuIcRAorZAJ9mI2AhJwFr1/9d1ZZ1D/s2XhIUzQCgihan
X0S1Os/QO9ULgmaUENvE+K4=
=aoiE
-----END PGP SIGNATURE-----

--DocE+STaALJfprDB--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20071115184615.GL20992>