webservices: Set and restore the full floating point control word.
Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
7c6fbebf68
commit
35c09b52d9
@ -2294,17 +2294,14 @@ static HRESULT str_to_uint64( const unsigned char *str, ULONG len, UINT64 max, U
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__i386__) || defined(__x86_64__)
|
BOOL set_fpword( unsigned short new, unsigned short *old )
|
||||||
|
|
||||||
#define RC_DOWN 0x100;
|
|
||||||
BOOL set_fp_rounding( unsigned short *save )
|
|
||||||
{
|
{
|
||||||
#ifdef __GNUC__
|
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
|
||||||
unsigned short fpword;
|
unsigned short fpword;
|
||||||
|
|
||||||
__asm__ __volatile__( "fstcw %0" : "=m" (fpword) );
|
__asm__ __volatile__( "fstcw %0" : "=m" (fpword) );
|
||||||
*save = fpword;
|
*old = fpword;
|
||||||
fpword |= RC_DOWN;
|
fpword = new;
|
||||||
__asm__ __volatile__( "fldcw %0" : : "m" (fpword) );
|
__asm__ __volatile__( "fldcw %0" : : "m" (fpword) );
|
||||||
return TRUE;
|
return TRUE;
|
||||||
#else
|
#else
|
||||||
@ -2312,25 +2309,15 @@ BOOL set_fp_rounding( unsigned short *save )
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
void restore_fp_rounding( unsigned short fpword )
|
|
||||||
|
void restore_fpword( unsigned short fpword )
|
||||||
{
|
{
|
||||||
#ifdef __GNUC__
|
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
|
||||||
__asm__ __volatile__( "fldcw %0" : : "m" (fpword) );
|
__asm__ __volatile__( "fldcw %0" : : "m" (fpword) );
|
||||||
#else
|
#else
|
||||||
FIXME( "not implemented\n" );
|
FIXME( "not implemented\n" );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
BOOL set_fp_rounding( unsigned short *save )
|
|
||||||
{
|
|
||||||
FIXME( "not implemented\n" );
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
void restore_fp_rounding( unsigned short fpword )
|
|
||||||
{
|
|
||||||
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 )
|
||||||
{
|
{
|
||||||
@ -2373,7 +2360,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_fp_rounding( &fpword )) return E_NOTIMPL;
|
if (!set_fpword( 0x37f, &fpword )) return E_NOTIMPL;
|
||||||
|
|
||||||
q = p;
|
q = p;
|
||||||
while (len && isdigit( *q )) { q++; len--; }
|
while (len && isdigit( *q )) { q++; len--; }
|
||||||
@ -2444,7 +2431,7 @@ static HRESULT str_to_double( const unsigned char *str, ULONG len, double *ret )
|
|||||||
hr = S_OK;
|
hr = S_OK;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
restore_fp_rounding( fpword );
|
restore_fpword( fpword );
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2065,9 +2065,28 @@ 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;
|
||||||
static const struct
|
static const struct
|
||||||
{
|
{
|
||||||
double val;
|
double val;
|
||||||
@ -2155,6 +2174,34 @@ 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 ))
|
||||||
|
{
|
||||||
|
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 );
|
||||||
|
|
||||||
|
hr = set_output( writer );
|
||||||
|
ok( hr == S_OK, "got %08x\n", hr );
|
||||||
|
hr = WsWriteStartElement( writer, NULL, &localname, &ns, NULL );
|
||||||
|
ok( hr == S_OK, "got %08x\n", hr );
|
||||||
|
|
||||||
|
text.value = 100000000000000;
|
||||||
|
hr = WsWriteText( writer, &text.text, NULL );
|
||||||
|
ok( hr == S_OK, "got %08x\n", hr );
|
||||||
|
|
||||||
|
hr = WsWriteEndElement( writer, NULL );
|
||||||
|
ok( hr == S_OK, "got %08x\n", hr );
|
||||||
|
check_output( writer, "<t>100000000000000</t>", __LINE__ );
|
||||||
|
|
||||||
|
get_fpword( &fpword );
|
||||||
|
ok( fpword == 0x1f7f, "got %04x\n", fpword );
|
||||||
|
set_fpword( 0x27f );
|
||||||
|
|
||||||
WsFreeWriter( writer );
|
WsFreeWriter( writer );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,8 +35,8 @@ WS_XML_UTF8_TEXT *alloc_utf8_text( const unsigned char *, ULONG ) DECLSPEC_HIDDE
|
|||||||
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_fp_rounding( unsigned short * ) DECLSPEC_HIDDEN;
|
BOOL set_fpword( unsigned short, unsigned short * ) DECLSPEC_HIDDEN;
|
||||||
void restore_fp_rounding( unsigned short ) DECLSPEC_HIDDEN;
|
void restore_fpword( unsigned short ) DECLSPEC_HIDDEN;
|
||||||
HRESULT set_output( WS_XML_WRITER * ) DECLSPEC_HIDDEN;
|
HRESULT set_output( WS_XML_WRITER * ) DECLSPEC_HIDDEN;
|
||||||
HRESULT set_input( WS_XML_READER *, char *, ULONG ) DECLSPEC_HIDDEN;
|
HRESULT set_input( WS_XML_READER *, char *, ULONG ) DECLSPEC_HIDDEN;
|
||||||
ULONG get_type_size( WS_TYPE, const WS_STRUCT_DESCRIPTION * ) DECLSPEC_HIDDEN;
|
ULONG get_type_size( WS_TYPE, const WS_STRUCT_DESCRIPTION * ) DECLSPEC_HIDDEN;
|
||||||
|
@ -1373,9 +1373,9 @@ static HRESULT text_to_utf8text( const WS_XML_TEXT *text, WS_XML_UTF8_TEXT **ret
|
|||||||
unsigned short fpword;
|
unsigned short fpword;
|
||||||
ULONG len;
|
ULONG len;
|
||||||
|
|
||||||
if (!set_fp_rounding( &fpword )) return E_NOTIMPL;
|
if (!set_fpword( 0x37f, &fpword )) return E_NOTIMPL;
|
||||||
len = format_double( &double_text->value, buf );
|
len = format_double( &double_text->value, buf );
|
||||||
restore_fp_rounding( fpword );
|
restore_fpword( fpword );
|
||||||
if (!len) return E_NOTIMPL;
|
if (!len) return E_NOTIMPL;
|
||||||
if (!(*ret = alloc_utf8_text( buf, len ))) return E_OUTOFMEMORY;
|
if (!(*ret = alloc_utf8_text( buf, len ))) return E_OUTOFMEMORY;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user