msvcrt: Implemented _clearfp for SSE2 and x86_64.

This commit is contained in:
Alexandre Julliard 2011-01-25 21:59:45 +01:00
parent 4b17ec7405
commit 98d7a021d6
1 changed files with 26 additions and 5 deletions

View File

@ -835,13 +835,34 @@ unsigned int CDECL _statusfp(void)
*/ */
unsigned int CDECL _clearfp(void) unsigned int CDECL _clearfp(void)
{ {
unsigned int retVal = _statusfp(); unsigned int flags = 0;
#if defined(__GNUC__) && defined(__i386__) #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
__asm__ __volatile__( "fnclex" ); unsigned long fpword;
__asm__ __volatile__( "fnstsw %0; fnclex" : "=m" (fpword) );
if (fpword & 0x1) flags |= MSVCRT__SW_INVALID;
if (fpword & 0x2) flags |= MSVCRT__SW_DENORMAL;
if (fpword & 0x4) flags |= MSVCRT__SW_ZERODIVIDE;
if (fpword & 0x8) flags |= MSVCRT__SW_OVERFLOW;
if (fpword & 0x10) flags |= MSVCRT__SW_UNDERFLOW;
if (fpword & 0x20) flags |= MSVCRT__SW_INEXACT;
if (sse2_supported)
{
__asm__ __volatile__( "stmxcsr %0" : "=m" (fpword) );
if (fpword & 0x1) flags |= MSVCRT__SW_INVALID;
if (fpword & 0x2) flags |= MSVCRT__SW_DENORMAL;
if (fpword & 0x4) flags |= MSVCRT__SW_ZERODIVIDE;
if (fpword & 0x8) flags |= MSVCRT__SW_OVERFLOW;
if (fpword & 0x10) flags |= MSVCRT__SW_UNDERFLOW;
if (fpword & 0x20) flags |= MSVCRT__SW_INEXACT;
fpword &= ~0x3f;
__asm__ __volatile__( "ldmxcsr %0" : : "m" (fpword) );
}
#else #else
FIXME(":Not Implemented\n"); FIXME( "not implemented\n" );
#endif #endif
return retVal; return flags;
} }
/********************************************************************* /*********************************************************************