Date: Sat, 17 Nov 2007 10:56:21 +1100 (EST) From: Bruce Evans <brde@optusnet.com.au> To: Peter Jeremy <peterjeremy@optushome.com.au> Cc: stable@freebsd.org, Pete French <petefrench@ticketswitch.com>, Bruce Evans <brde@optusnet.com.au>, bde@freebsd.org Subject: Re: Float problen running i386 inary on amd64 Message-ID: <20071117091837.R65837@delplex.bde.org> In-Reply-To: <20071116203512.GD20992@server.vk2pj.dyndns.org> References: <20071115062002.GK89746@server.vk2pj.dyndns.org> <E1IseEn-000315-Uy@dilbert.ticketswitch.com> <20071115184615.GL20992@server.vk2pj.dyndns.org> <20071117025943.P64582@delplex.bde.org> <20071116203512.GD20992@server.vk2pj.dyndns.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Sat, 17 Nov 2007, Peter Jeremy wrote: > On Sat, Nov 17, 2007 at 04:53:22AM +1100, Bruce Evans wrote: >> Behaviour like this should be expected on i386 but not on amd64. It >> gives the well-known property of the sin() function, that sin(x) != sin(x) >> for almost all x (!). It happens because expressions _may_ be evaluated >> in extra precision (this is perfectly standard), so identical expressions >> may sometimes be evaluated in different precisions even, or especially, >> if they are on the same line. > > Thank you for your detailed analysis. Hwever, I believe you missed > the critical point (I may have removed too much reference to the > actual problem that Pete French saw): I can take a program that was > statically compiled on FreeBSD/i386, run it in legacy (i386) mode on > FreeBSD-6.3/amd64 and get different results. > > Another (admittedly contrived) example: > ... Ah, that explains it. This was also a longstanding bug in the Linux emulator. linux_setregs() wasn't fixed to use the Linux npx control word until relatively recently (2005). Linux libraries used to set the control word in the C library (crt), which I think is the right place to initialize it since the correct initialization may depend on the language, so the bug wasn't so obvious at first. > This is identical code being executed in supposedly equivalent > environments giving different results. > > I believe the fix is to initialise the FPU using __INITIAL_NPXCW__ in > ia32_setregs(), though I'm not sure how difficult this is in reality. Yes, that is the right fix. It is moderately difficult to do correctly. linux_setregs() now just uses fldcw(&control) where control = __LINUX_NPXCW__. This depends on bugs to work, since direct accesses to the FPU in the kernel are not supported. They cause a DNA trap which should be fatal. amd64 is supposed to print a message about this error, but it apparently doesn't else log files would be fuller. i386 doesn't even print a message. npxdna() and fpudna() check related invariants but not this one. Correct code would do something like {fpu,npx}xinit(control) to initialize the control word. setregs() in RELENG_[1-4] does exactly that -- npxinit() hides the complications. Now {fpu,npx}init() is only called once or twice at boot time for each CPU, and the complications are a little larger since most initialization is delayed until the DNA trap ({fpu,npx}init() now mainly sets up a copy of the initial FPU state in memory for the trap handler to load later, and it cannot set up per-thread state since the copy in memory is a global default). The complications for delayed initialization are mainly to optimize switching of the FPU state for signal handling, but are also used for exec. Another complication here is that signal handlers should be given the default control word. This is much more broken than for setregs: - there are sysent hooks for sendsig and sigreturn, but none for setting registers in sendsig. - all FreeBSD sendsig's end up using the gobal default initial FPU state (if they support switching the FPU state at all). - all Linux sendsig's are missing support for switching the FPU state. - suppose that the initial FPU (or even CPU) state is language-dependent and this is implemented mainly in the language runtime startup. sendsig's would have a hard time determining the languages' defaults so as to set them. The languages would need to set the defaults in signal trampolines. Bruce
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20071117091837.R65837>