From: André Hentschel Subject: [PATCH 1/2] webservices: Implement floating point handling for ARM Message-Id: <7c0ae22e-cce1-2ce4-69fe-6a6fc48c1c5a@dawncrow.de> Date: Sat, 11 Nov 2017 14:03:35 +0100 Signed-off-by: André Hentschel --- dlls/webservices/reader.c | 22 ++++++++++++++++------ dlls/webservices/webservices_private.h | 4 ++-- dlls/webservices/writer.c | 4 ++-- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c index 9d024a3..81f1bb6 100644 --- a/dlls/webservices/reader.c +++ b/dlls/webservices/reader.c @@ -3596,26 +3596,36 @@ 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 ) +BOOL init_fpword( unsigned long *old ) { #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) - unsigned short fpword; + unsigned long fpword; __asm__ __volatile__( "fstcw %0" : "=m" (fpword) ); *old = fpword; - fpword = new; + fpword = 0x37f; __asm__ __volatile__( "fldcw %0" : : "m" (fpword) ); return TRUE; +#elif defined(__arm__) + unsigned long fpword; + + __asm__ __volatile__( "vmrs %0, fpscr" : "=r" (fpword) ); + *old = fpword; + fpword = 0; + __asm__ __volatile__( "vmsr fpscr, %0" : : "r" (fpword) ); + return TRUE; #else FIXME( "not implemented\n" ); return FALSE; #endif } -void restore_fpword( unsigned short fpword ) +void restore_fpword( unsigned long fpword ) { #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) __asm__ __volatile__( "fldcw %0" : : "m" (fpword) ); +#elif defined(__arm__) + __asm__ __volatile__( "vmsr fpscr, %0" : : "r" (fpword) ); #else FIXME( "not implemented\n" ); #endif @@ -3631,7 +3641,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 long fpword; while (len && read_isspace( *p )) { p++; len--; } while (len && read_isspace( p[len - 1] )) { len--; } @@ -3662,7 +3672,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; + if (!init_fpword( &fpword )) return E_NOTIMPL; q = p; while (len && isdigit( *q )) { q++; len--; } diff --git a/dlls/webservices/webservices_private.h b/dlls/webservices/webservices_private.h index f8cc6d9..cf7d480 100644 --- a/dlls/webservices/webservices_private.h +++ b/dlls/webservices/webservices_private.h @@ -60,8 +60,8 @@ 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; +BOOL init_fpword( unsigned long * ) DECLSPEC_HIDDEN; +void restore_fpword( unsigned long ) 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 f6917c6..f30d5d6 100644 --- a/dlls/webservices/writer.c +++ b/dlls/webservices/writer.c @@ -2159,10 +2159,10 @@ static HRESULT text_to_utf8text( const WS_XML_TEXT *text, const WS_XML_UTF8_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 short fpword; + unsigned long fpword; ULONG len; - if (!set_fpword( 0x37f, &fpword )) return E_NOTIMPL; + if (!init_fpword( &fpword )) return E_NOTIMPL; len = format_double( &double_text->value, buf ); restore_fpword( fpword ); if (!len) return E_NOTIMPL; -- 2.7.4