Qian Hong : ntdll/tests: Add SIMD exception test for floating point invalid operation fault.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Dec 3 09:56:21 CST 2015


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

Author: Qian Hong <qhong at codeweavers.com>
Date:   Thu Dec  3 00:06:50 2015 +0800

ntdll/tests: Add SIMD exception test for floating point invalid operation fault.

Signed-off-by: Qian Hong <qhong at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntdll/tests/exception.c | 57 +++++++++++++++++++++++++++++++-------------
 1 file changed, 41 insertions(+), 16 deletions(-)

diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c
index 8477988..221d86a 100644
--- a/dlls/ntdll/tests/exception.c
+++ b/dlls/ntdll/tests/exception.c
@@ -1015,22 +1015,25 @@ static DWORD simd_fault_handler( EXCEPTION_RECORD *rec, EXCEPTION_REGISTRATION_R
         context->Eip += 3; /* skip addps */
         return ExceptionContinueExecution;
     }
-
-    /* stage 2 - divide by zero fault */
-    if( rec->ExceptionCode == EXCEPTION_ILLEGAL_INSTRUCTION)
-        skip("system doesn't support SIMD exceptions\n");
-    else {
-        ok( rec->ExceptionCode ==  STATUS_FLOAT_MULTIPLE_TRAPS,
-            "exception code: %#x, should be %#x\n",
-            rec->ExceptionCode,  STATUS_FLOAT_MULTIPLE_TRAPS);
-        ok( rec->NumberParameters == 1 || broken(is_wow64 && rec->NumberParameters == 2),
-            "# of params: %i, should be 1\n",
-            rec->NumberParameters);
-        if( rec->NumberParameters == 1 )
-            ok( rec->ExceptionInformation[0] == 0, "param #1: %lx, should be 0\n", rec->ExceptionInformation[0]);
+    else if ( *stage == 2 || *stage == 3 ) {
+        /* stage 2 - divide by zero fault */
+        /* stage 3 - invalid operation fault */
+        if( rec->ExceptionCode == EXCEPTION_ILLEGAL_INSTRUCTION)
+            skip("system doesn't support SIMD exceptions\n");
+        else {
+            ok( rec->ExceptionCode ==  STATUS_FLOAT_MULTIPLE_TRAPS,
+                "exception code: %#x, should be %#x\n",
+                rec->ExceptionCode,  STATUS_FLOAT_MULTIPLE_TRAPS);
+            ok( rec->NumberParameters == 1 || broken(is_wow64 && rec->NumberParameters == 2),
+                "# of params: %i, should be 1\n",
+                rec->NumberParameters);
+            if( rec->NumberParameters == 1 )
+                ok( rec->ExceptionInformation[0] == 0, "param #1: %lx, should be 0\n", rec->ExceptionInformation[0]);
+        }
+        context->Eip += 3; /* skip divps */
     }
-
-    context->Eip += 3; /* skip divps */
+    else
+        ok(FALSE, "unexpected stage %x\n", *stage);
 
     return ExceptionContinueExecution;
 }
@@ -1054,6 +1057,21 @@ static const BYTE simd_exception_test[] = {
     0xc3,                                /* ret */
 };
 
+static const BYTE simd_exception_test2[] = {
+    0x83, 0xec, 0x4,                     /* sub $0x4, %esp       */
+    0x0f, 0xae, 0x1c, 0x24,              /* stmxcsr (%esp)       */
+    0x8b, 0x04, 0x24,                    /* mov    (%esp),%eax   * store mxcsr */
+    0x66, 0x81, 0x24, 0x24, 0x7f, 0xff,  /* andw $0xff7f,(%esp)  * enable invalid       */
+    0x0f, 0xae, 0x14, 0x24,              /* ldmxcsr (%esp)       * operation exceptions */
+    0x0f, 0x57, 0xc9,                    /* xorps  %xmm1,%xmm1   * clear dividend */
+    0x0f, 0x57, 0xc0,                    /* xorps  %xmm0,%xmm0   * clear divisor  */
+    0x0f, 0x5e, 0xc8,                    /* divps  %xmm0,%xmm1   * generate fault */
+    0x89, 0x04, 0x24,                    /* mov    %eax,(%esp)   * restore to old mxcsr */
+    0x0f, 0xae, 0x14, 0x24,              /* ldmxcsr (%esp)       */
+    0x83, 0xc4, 0x04,                    /* add    $0x4,%esp     */
+    0xc3,                                /* ret */
+};
+
 static const BYTE sse_check[] = {
     0x0f, 0x58, 0xc8,                    /* addps  %xmm0,%xmm1 */
     0xc3,                                /* ret */
@@ -1077,7 +1095,14 @@ static void test_simd_exceptions(void)
     got_exception = 0;
     run_exception_test(simd_fault_handler, &stage, simd_exception_test,
                        sizeof(simd_exception_test), 0);
-    ok( got_exception == 1, "got exception: %i, should be 1\n", got_exception);
+    ok(got_exception == 1, "got exception: %i, should be 1\n", got_exception);
+
+    /* generate a SIMD exception, test FPE_FLTINV */
+    stage = 3;
+    got_exception = 0;
+    run_exception_test(simd_fault_handler, &stage, simd_exception_test2,
+                       sizeof(simd_exception_test2), 0);
+    ok(got_exception == 1, "got exception: %i, should be 1\n", got_exception);
 }
 
 struct fpu_exception_info




More information about the wine-cvs mailing list