diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c index 664bfbeb634..181739650e0 100644 --- a/dlls/webservices/reader.c +++ b/dlls/webservices/reader.c @@ -18,6 +18,7 @@ #include #include +#include #include "windef.h" #include "winbase.h" @@ -3723,31 +3724,6 @@ static HRESULT str_to_uint64( const unsigned char *str, ULONG len, UINT64 max, U return S_OK; } -BOOL set_fpword( unsigned short new, unsigned short *old ) -{ -#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) - unsigned short fpword; - - __asm__ __volatile__( "fstcw %0" : "=m" (fpword) ); - *old = fpword; - fpword = new; - __asm__ __volatile__( "fldcw %0" : : "m" (fpword) ); - return TRUE; -#else - FIXME( "not implemented\n" ); - return FALSE; -#endif -} - -void restore_fpword( unsigned short fpword ) -{ -#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) - __asm__ __volatile__( "fldcw %0" : : "m" (fpword) ); -#else - FIXME( "not implemented\n" ); -#endif -} - static HRESULT str_to_double( const unsigned char *str, ULONG len, double *ret ) { static const unsigned __int64 nan = 0xfff8000000000000; @@ -3758,7 +3734,7 @@ static HRESULT str_to_double( const unsigned char *str, ULONG len, double *ret ) int sign = 1, exp_sign = 1, exp = 0, exp_tmp = 0, neg_exp, i, nb_digits, have_digits; unsigned __int64 val = 0, tmp; long double exp_val = 1.0, exp_mul = 10.0; - unsigned short fpword; + unsigned int fpword = _control87( 0, 0 ); while (len && read_isspace( *p )) { p++; len--; } while (len && read_isspace( p[len - 1] )) { len--; } @@ -3789,7 +3765,7 @@ static HRESULT str_to_double( const unsigned char *str, ULONG len, double *ret ) else if (*p == '+') { p++; len--; }; if (!len) return S_OK; - if (!set_fpword( 0x37f, &fpword )) return E_NOTIMPL; + _control87( _MCW_EM | _RC_NEAR | _PC_64, _MCW_EM | _MCW_RC | _MCW_PC ); q = p; while (len && isdigit( *q )) { q++; len--; } @@ -3860,7 +3836,7 @@ static HRESULT str_to_double( const unsigned char *str, ULONG len, double *ret ) hr = S_OK; done: - restore_fpword( fpword ); + _control87( fpword, _MCW_EM | _MCW_RC | _MCW_PC ); return hr; } diff --git a/dlls/webservices/tests/writer.c b/dlls/webservices/tests/writer.c index 18c4b7e284b..65e672a4247 100644 --- a/dlls/webservices/tests/writer.c +++ b/dlls/webservices/tests/writer.c @@ -18,6 +18,7 @@ #include #include +#include #include "windows.h" #include "rpc.h" #include "webservices.h" @@ -2220,28 +2221,10 @@ static void test_text_types(void) WsFreeWriter( writer ); } -static BOOL get_fpword( unsigned short *ret ) -{ -#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) - unsigned short fpword; - __asm__ __volatile__( "fstcw %0" : "=m" (fpword) ); - *ret = fpword; - return TRUE; -#endif - return FALSE; -} - -static void set_fpword( unsigned short fpword ) -{ -#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) - __asm__ __volatile__( "fldcw %0" : : "m" (fpword) ); -#endif -} - static void test_double(void) { WS_XML_STRING localname = {1, (BYTE *)"t"}, ns = {0, NULL}; - unsigned short fpword; + unsigned int fpword, fpword_orig; static const struct { double val; @@ -2329,16 +2312,9 @@ static void test_double(void) ok( hr == S_OK, "got %08x\n", hr ); check_output( writer, "-INF", __LINE__ ); - if (!get_fpword( &fpword )) - { - skip( "can't get floating point control word\n" ); - WsFreeWriter( writer ); - return; - } - ok( fpword == 0x27f, "got %04x\n", fpword ); - set_fpword( 0x1f7f ); - get_fpword( &fpword ); - ok( fpword == 0x1f7f, "got %04x\n", fpword ); + fpword_orig = _control87( 0, 0 ); + fpword = _control87( _MCW_EM | _RC_CHOP | _PC_64, _MCW_EM | _MCW_RC | _MCW_PC ); + ok( fpword == (_MCW_EM | _RC_CHOP | _PC_64), "got %08x\n", fpword ); hr = set_output( writer ); ok( hr == S_OK, "got %08x\n", hr ); @@ -2353,9 +2329,9 @@ static void test_double(void) ok( hr == S_OK, "got %08x\n", hr ); check_output( writer, "100000000000000", __LINE__ ); - get_fpword( &fpword ); - ok( fpword == 0x1f7f, "got %04x\n", fpword ); - set_fpword( 0x27f ); + fpword = _control87( 0, 0 ); + ok( fpword == (_MCW_EM | _RC_CHOP | _PC_64), "got %08x\n", fpword ); + _control87( fpword_orig, _MCW_EM | _MCW_RC | _MCW_PC ); WsFreeWriter( writer ); } diff --git a/dlls/webservices/webservices_private.h b/dlls/webservices/webservices_private.h index 9ca470c82b2..b12032060f7 100644 --- a/dlls/webservices/webservices_private.h +++ b/dlls/webservices/webservices_private.h @@ -65,8 +65,6 @@ void free_xml_string( WS_XML_STRING * ) DECLSPEC_HIDDEN; HRESULT append_attribute( WS_XML_ELEMENT_NODE *, WS_XML_ATTRIBUTE * ) DECLSPEC_HIDDEN; void free_attribute( WS_XML_ATTRIBUTE * ) DECLSPEC_HIDDEN; WS_TYPE map_value_type( WS_VALUE_TYPE ) DECLSPEC_HIDDEN; -BOOL set_fpword( unsigned short, unsigned short * ) DECLSPEC_HIDDEN; -void restore_fpword( unsigned short ) DECLSPEC_HIDDEN; ULONG get_type_size( WS_TYPE, const void * ) DECLSPEC_HIDDEN; HRESULT read_header( WS_XML_READER *, const WS_XML_STRING *, const WS_XML_STRING *, WS_TYPE, const void *, WS_READ_OPTION, WS_HEAP *, void *, ULONG ) DECLSPEC_HIDDEN; diff --git a/dlls/webservices/writer.c b/dlls/webservices/writer.c index f750859fbcd..021c961c949 100644 --- a/dlls/webservices/writer.c +++ b/dlls/webservices/writer.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include "windef.h" @@ -1193,12 +1194,12 @@ HRESULT text_to_utf8text( const WS_XML_TEXT *text, const WS_XML_UTF8_TEXT *old, { const WS_XML_DOUBLE_TEXT *double_text = (const WS_XML_DOUBLE_TEXT *)text; unsigned char buf[32]; /* "-1.1111111111111111E-308", oversized to address Valgrind limitations */ - unsigned short fpword; + unsigned int fpword = _control87( 0, 0 ); ULONG len; - if (!set_fpword( 0x37f, &fpword )) return E_NOTIMPL; + _control87( _MCW_EM | _RC_NEAR | _PC_64, _MCW_EM | _MCW_RC | _MCW_PC ); len = format_double( &double_text->value, buf ); - restore_fpword( fpword ); + _control87( fpword, _MCW_EM | _MCW_RC | _MCW_PC ); if (!len) return E_NOTIMPL; if (!(*ret = alloc_utf8_text( NULL, len_old + len ))) return E_OUTOFMEMORY;