webservices: Use _control87() instead of directly manipulating the FPU register.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
eecaf487af
commit
311f6c8453
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <float.h>
|
||||||
|
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
#include "winbase.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;
|
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 HRESULT str_to_double( const unsigned char *str, ULONG len, double *ret )
|
||||||
{
|
{
|
||||||
static const unsigned __int64 nan = 0xfff8000000000000;
|
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;
|
int sign = 1, exp_sign = 1, exp = 0, exp_tmp = 0, neg_exp, i, nb_digits, have_digits;
|
||||||
unsigned __int64 val = 0, tmp;
|
unsigned __int64 val = 0, tmp;
|
||||||
long double exp_val = 1.0, exp_mul = 10.0;
|
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 )) { p++; len--; }
|
||||||
while (len && read_isspace( p[len - 1] )) { 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--; };
|
else if (*p == '+') { p++; len--; };
|
||||||
if (!len) return S_OK;
|
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;
|
q = p;
|
||||||
while (len && isdigit( *q )) { q++; len--; }
|
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;
|
hr = S_OK;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
restore_fpword( fpword );
|
_control87( fpword, _MCW_EM | _MCW_RC | _MCW_PC );
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <float.h>
|
||||||
#include "windows.h"
|
#include "windows.h"
|
||||||
#include "rpc.h"
|
#include "rpc.h"
|
||||||
#include "webservices.h"
|
#include "webservices.h"
|
||||||
|
@ -2220,28 +2221,10 @@ static void test_text_types(void)
|
||||||
WsFreeWriter( writer );
|
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)
|
static void test_double(void)
|
||||||
{
|
{
|
||||||
WS_XML_STRING localname = {1, (BYTE *)"t"}, ns = {0, NULL};
|
WS_XML_STRING localname = {1, (BYTE *)"t"}, ns = {0, NULL};
|
||||||
unsigned short fpword;
|
unsigned int fpword, fpword_orig;
|
||||||
static const struct
|
static const struct
|
||||||
{
|
{
|
||||||
double val;
|
double val;
|
||||||
|
@ -2329,16 +2312,9 @@ static void test_double(void)
|
||||||
ok( hr == S_OK, "got %08x\n", hr );
|
ok( hr == S_OK, "got %08x\n", hr );
|
||||||
check_output( writer, "<t>-INF</t>", __LINE__ );
|
check_output( writer, "<t>-INF</t>", __LINE__ );
|
||||||
|
|
||||||
if (!get_fpword( &fpword ))
|
fpword_orig = _control87( 0, 0 );
|
||||||
{
|
fpword = _control87( _MCW_EM | _RC_CHOP | _PC_64, _MCW_EM | _MCW_RC | _MCW_PC );
|
||||||
skip( "can't get floating point control word\n" );
|
ok( fpword == (_MCW_EM | _RC_CHOP | _PC_64), "got %08x\n", fpword );
|
||||||
WsFreeWriter( writer );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ok( fpword == 0x27f, "got %04x\n", fpword );
|
|
||||||
set_fpword( 0x1f7f );
|
|
||||||
get_fpword( &fpword );
|
|
||||||
ok( fpword == 0x1f7f, "got %04x\n", fpword );
|
|
||||||
|
|
||||||
hr = set_output( writer );
|
hr = set_output( writer );
|
||||||
ok( hr == S_OK, "got %08x\n", hr );
|
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 );
|
ok( hr == S_OK, "got %08x\n", hr );
|
||||||
check_output( writer, "<t>100000000000000</t>", __LINE__ );
|
check_output( writer, "<t>100000000000000</t>", __LINE__ );
|
||||||
|
|
||||||
get_fpword( &fpword );
|
fpword = _control87( 0, 0 );
|
||||||
ok( fpword == 0x1f7f, "got %04x\n", fpword );
|
ok( fpword == (_MCW_EM | _RC_CHOP | _PC_64), "got %08x\n", fpword );
|
||||||
set_fpword( 0x27f );
|
_control87( fpword_orig, _MCW_EM | _MCW_RC | _MCW_PC );
|
||||||
|
|
||||||
WsFreeWriter( writer );
|
WsFreeWriter( writer );
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
HRESULT append_attribute( WS_XML_ELEMENT_NODE *, WS_XML_ATTRIBUTE * ) DECLSPEC_HIDDEN;
|
||||||
void free_attribute( WS_XML_ATTRIBUTE * ) DECLSPEC_HIDDEN;
|
void free_attribute( WS_XML_ATTRIBUTE * ) DECLSPEC_HIDDEN;
|
||||||
WS_TYPE map_value_type( WS_VALUE_TYPE ) 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;
|
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,
|
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;
|
const void *, WS_READ_OPTION, WS_HEAP *, void *, ULONG ) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <float.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#include "windef.h"
|
#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;
|
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 char buf[32]; /* "-1.1111111111111111E-308", oversized to address Valgrind limitations */
|
||||||
unsigned short fpword;
|
unsigned int fpword = _control87( 0, 0 );
|
||||||
ULONG len;
|
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 );
|
len = format_double( &double_text->value, buf );
|
||||||
restore_fpword( fpword );
|
_control87( fpword, _MCW_EM | _MCW_RC | _MCW_PC );
|
||||||
if (!len) return E_NOTIMPL;
|
if (!len) return E_NOTIMPL;
|
||||||
|
|
||||||
if (!(*ret = alloc_utf8_text( NULL, len_old + len ))) return E_OUTOFMEMORY;
|
if (!(*ret = alloc_utf8_text( NULL, len_old + len ))) return E_OUTOFMEMORY;
|
||||||
|
|
Loading…
Reference in New Issue