[PATCH 1/2] webservices: Implement floating point handling for ARM

André Hentschel nerv at dawncrow.de
Sat Nov 11 07:03:35 CST 2017


Signed-off-by: André Hentschel <nerv at dawncrow.de>
---
 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





More information about the wine-devel mailing list