delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2005/03/02/07:06:33

Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm
List-Subscribe: <mailto:cygwin-subscribe AT cygwin DOT com>
List-Archive: <http://sourceware.org/ml/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-help AT cygwin DOT com>, <http://sourceware.org/ml/#faqs>
Sender: cygwin-owner AT cygwin DOT com
Mail-Followup-To: cygwin AT cygwin DOT com
Delivered-To: mailing list cygwin AT cygwin DOT com
From: "Ralf B. Schulz" <r DOT schulz AT dkfz-heidelberg DOT de>
Organization: DKFZ
To: cygwin AT cygwin DOT com
Subject: loading of wsock32 disturbs FPU
Date: Wed, 2 Mar 2005 13:06:32 +0100
User-Agent: KMail/1.5
MIME-Version: 1.0
Message-Id: <200503021306.32969.r.schulz@dkfz.de>

This is a follow-up on thread "1.5.12: FPU affected by gethostname call". It 
shows that calling some functions of the windows API will affect the floating 
point unit so that all calculation are performed with double precision only, 
instead of long double precision.

After careful examination, the problem is as follows: after loading of some 
DLLs (in particular wsock32.dll) it seems that some flags of the floating 
point unit that determine the accuracy of floating point calculations are 
changed.

This happens at least on the following two cygwin systems:

cygwin 1.5.12, gcc 3.3.3, AMD Athlon XP under Windows XP SP1
cygwin 1.5.13, gcc 3.3.3, Intel Pentium III cpu under Windows 2000 SP

So the error is not CPU related (not a matter of Intel or AMD, I mean). The 
following program shows this effect:

#include <netdb.h>
#include <limits>
#include <iostream>

void check_fpu()
{
   volatile long double x=1.0;
   x += std::numeric_limits<long double>::epsilon();
   std::cout << "FPU test " << ( x != 1. ? "OK" : "FAILED" ) << std::endl;
}

int main()
{
   // FIRST: check FPU
   check_fpu();

   // SECOND: make call to _any_ function in wsock32.dll and check
   gethostbyname("random");
   check_fpu();

   // THIRD: reinitialize FPU, check
   asm("finit");
   check_fpu();

   // FOURTH: call _any other_ function of wsock32.dll and check
   char buf[100];
   gethostname(buf,99);
   check_fpu();

   return 0;
}

The screen output on my systems always is:

FPU test OK
FPU test FAILED
FPU test OK
FPU test OK

So I conclude:
a) when loading the DLL, i.e. with the first call of any function in wsock32, 
the FPU goes into 64 bit mode
b) the assembler instruction "finit" rsets it to 80-bit mode
c) after that, any other calls to the DLL, which now resides in memory, is not 
disturbing the FPU, that means whatever it is that happens to the FPU, it 
happens in the DLL startup code or in the DLL loader.

-Ralf

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019