From 98d7a021d62b4ad3d880f35888f8ae7b7f7b26b5 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 25 Jan 2011 21:59:45 +0100 Subject: [PATCH] msvcrt: Implemented _clearfp for SSE2 and x86_64. --- dlls/msvcrt/math.c | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/dlls/msvcrt/math.c b/dlls/msvcrt/math.c index 988ccc793b8..6755fbbf40c 100644 --- a/dlls/msvcrt/math.c +++ b/dlls/msvcrt/math.c @@ -835,13 +835,34 @@ unsigned int CDECL _statusfp(void) */ unsigned int CDECL _clearfp(void) { - unsigned int retVal = _statusfp(); -#if defined(__GNUC__) && defined(__i386__) - __asm__ __volatile__( "fnclex" ); + unsigned int flags = 0; +#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) + 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 - FIXME(":Not Implemented\n"); + FIXME( "not implemented\n" ); #endif - return retVal; + return flags; } /*********************************************************************