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