Piotr Caban : msvcr120: Add _except1 implementation.

Alexandre Julliard julliard at winehq.org
Fri Feb 17 14:37:12 CST 2017


Module: wine
Branch: master
Commit: 10200af74142c786ca8c7594bfc1fb3ad9cb0ab3
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=10200af74142c786ca8c7594bfc1fb3ad9cb0ab3

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Fri Feb 17 15:54:25 2017 +0100

msvcr120: Add _except1 implementation.

Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 .../api-ms-win-crt-math-l1-1-0.spec                |  2 +-
 dlls/msvcr120/msvcr120.spec                        |  2 +-
 dlls/msvcr120_app/msvcr120_app.spec                |  2 +-
 dlls/msvcrt/math.c                                 | 92 ++++++++++++++++++++++
 dlls/ucrtbase/ucrtbase.spec                        |  2 +-
 5 files changed, 96 insertions(+), 4 deletions(-)

diff --git a/dlls/api-ms-win-crt-math-l1-1-0/api-ms-win-crt-math-l1-1-0.spec b/dlls/api-ms-win-crt-math-l1-1-0/api-ms-win-crt-math-l1-1-0.spec
index 8ff4c58..d5ade42 100644
--- a/dlls/api-ms-win-crt-math-l1-1-0/api-ms-win-crt-math-l1-1-0.spec
+++ b/dlls/api-ms-win-crt-math-l1-1-0/api-ms-win-crt-math-l1-1-0.spec
@@ -62,7 +62,7 @@
 @ stub _dsin
 @ cdecl _dtest(ptr) ucrtbase._dtest
 @ stub _dunscale
-@ stub _except1
+@ cdecl _except1(long long double double long ptr) ucrtbase._except1
 @ stub _fd_int
 @ cdecl _fdclass(float) ucrtbase._fdclass
 @ stub _fdexp
diff --git a/dlls/msvcr120/msvcr120.spec b/dlls/msvcr120/msvcr120.spec
index 62481c0..db2ae9c 100644
--- a/dlls/msvcr120/msvcr120.spec
+++ b/dlls/msvcr120/msvcr120.spec
@@ -1124,7 +1124,7 @@
 @ extern _environ MSVCRT__environ
 @ cdecl _eof(long) MSVCRT__eof
 @ cdecl _errno() MSVCRT__errno
-@ stub _except1
+@ cdecl _except1(long long double double long ptr)
 @ cdecl -arch=i386 _except_handler2(ptr ptr ptr ptr)
 @ cdecl -arch=i386 _except_handler3(ptr ptr ptr ptr)
 @ cdecl -arch=i386 _except_handler4_common(ptr ptr ptr ptr ptr ptr)
diff --git a/dlls/msvcr120_app/msvcr120_app.spec b/dlls/msvcr120_app/msvcr120_app.spec
index a74a140..849e135 100644
--- a/dlls/msvcr120_app/msvcr120_app.spec
+++ b/dlls/msvcr120_app/msvcr120_app.spec
@@ -1060,7 +1060,7 @@
 @ extern _environ msvcr120._environ
 @ cdecl _eof(long) msvcr120._eof
 @ cdecl _errno() msvcr120._errno
-@ stub _except1
+@ cdecl _except1(long long double double long ptr) msvcr120._except1
 @ cdecl -arch=i386 _except_handler2(ptr ptr ptr ptr) msvcr120._except_handler2
 @ cdecl -arch=i386 _except_handler3(ptr ptr ptr ptr) msvcr120._except_handler3
 @ cdecl -arch=i386 _except_handler4_common(ptr ptr ptr ptr ptr ptr) msvcr120._except_handler4_common
diff --git a/dlls/msvcrt/math.c b/dlls/msvcrt/math.c
index 74685d4..857561b 100644
--- a/dlls/msvcrt/math.c
+++ b/dlls/msvcrt/math.c
@@ -2986,3 +2986,95 @@ float CDECL MSVCR120_nanf(const char *tagp)
 {
     return NAN;
 }
+
+/*********************************************************************
+ *      _except1 (MSVCR120.@)
+ *  TODO:
+ *   - find meaning of ignored cw and operation bits
+ *   - unk parameter
+ */
+double CDECL _except1(DWORD fpe, _FP_OPERATION_CODE op, double arg, double res, DWORD cw, void *unk)
+{
+    ULONG_PTR exception_arg;
+    DWORD exception = 0;
+    MSVCRT_fenv_t env;
+    DWORD fpword = 0;
+    WORD operation;
+
+    TRACE("(%x %x %lf %lf %x %p)\n", fpe, op, arg, res, cw, unk);
+
+#ifdef _WIN64
+    cw = ((cw >> 7) & 0x3f) | ((cw >> 3) & 0xc00);
+#endif
+    operation = op << 5;
+    exception_arg = (ULONG_PTR)&operation;
+
+    MSVCRT_fegetenv(&env);
+
+    if (fpe & 0x1) { /* overflow */
+        if ((fpe == 0x1 && (cw & 0x8)) || (fpe==0x11 && (cw & 0x28))) {
+            /* 32-bit version also sets SW_INEXACT here */
+            env.status |= MSVCRT__SW_OVERFLOW;
+            if (fpe & 0x10) env.status |= MSVCRT__SW_INEXACT;
+            res = signbit(res) ? -INFINITY : INFINITY;
+        } else {
+            exception = EXCEPTION_FLT_OVERFLOW;
+        }
+    } else if (fpe & 0x2) { /* underflow */
+        if ((fpe == 0x2 && (cw & 0x10)) || (fpe==0x12 && (cw & 0x30))) {
+            env.status |= MSVCRT__SW_UNDERFLOW;
+            if (fpe & 0x10) env.status |= MSVCRT__SW_INEXACT;
+            res = signbit(res) ? -0.0 : 0.0;
+        } else {
+            exception = EXCEPTION_FLT_UNDERFLOW;
+        }
+    } else if (fpe & 0x4) { /* zerodivide */
+        if ((fpe == 0x4 && (cw & 0x4)) || (fpe==0x14 && (cw & 0x24))) {
+            env.status |= MSVCRT__SW_ZERODIVIDE;
+            if (fpe & 0x10) env.status |= MSVCRT__SW_INEXACT;
+        } else {
+            exception = EXCEPTION_FLT_DIVIDE_BY_ZERO;
+        }
+    } else if (fpe & 0x8) { /* invalid */
+        if (fpe == 0x8 && (cw & 0x1)) {
+            env.status |= MSVCRT__SW_INVALID;
+        } else {
+            exception = EXCEPTION_FLT_INVALID_OPERATION;
+        }
+    } else if (fpe & 0x10) { /* inexact */
+        if (fpe == 0x10 && (cw & 0x20)) {
+            env.status |= MSVCRT__SW_INEXACT;
+        } else {
+            exception = EXCEPTION_FLT_INEXACT_RESULT;
+        }
+    }
+
+    if (exception)
+        env.status = 0;
+    MSVCRT_fesetenv(&env);
+    if (exception)
+        RaiseException(exception, 0, 1, &exception_arg);
+
+    if (cw & 0x1) fpword |= MSVCRT__EM_INVALID;
+    if (cw & 0x2) fpword |= MSVCRT__EM_DENORMAL;
+    if (cw & 0x4) fpword |= MSVCRT__EM_ZERODIVIDE;
+    if (cw & 0x8) fpword |= MSVCRT__EM_OVERFLOW;
+    if (cw & 0x10) fpword |= MSVCRT__EM_UNDERFLOW;
+    if (cw & 0x20) fpword |= MSVCRT__EM_INEXACT;
+    switch (cw & 0xc00)
+    {
+        case 0xc00: fpword |= MSVCRT__RC_UP|MSVCRT__RC_DOWN; break;
+        case 0x800: fpword |= MSVCRT__RC_UP; break;
+        case 0x400: fpword |= MSVCRT__RC_DOWN; break;
+    }
+    switch (cw & 0x300)
+    {
+        case 0x0:   fpword |= MSVCRT__PC_24; break;
+        case 0x200: fpword |= MSVCRT__PC_53; break;
+        case 0x300: fpword |= MSVCRT__PC_64; break;
+    }
+    if (cw & 0x1000) fpword |= MSVCRT__IC_AFFINE;
+    _control87(fpword, 0xffffffff);
+
+    return res;
+}
diff --git a/dlls/ucrtbase/ucrtbase.spec b/dlls/ucrtbase/ucrtbase.spec
index 7602698..5c97d8b 100644
--- a/dlls/ucrtbase/ucrtbase.spec
+++ b/dlls/ucrtbase/ucrtbase.spec
@@ -271,7 +271,7 @@
 @ cdecl _endthreadex(long)
 @ cdecl _eof(long) MSVCRT__eof
 @ cdecl _errno() MSVCRT__errno
-@ stub _except1
+@ cdecl _except1(long long double double long ptr)
 @ cdecl -arch=i386 _except_handler2(ptr ptr ptr ptr)
 @ cdecl -arch=i386 _except_handler3(ptr ptr ptr ptr)
 @ cdecl -arch=i386 _except_handler4_common(ptr ptr ptr ptr ptr ptr)




More information about the wine-cvs mailing list