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

Signed-off-by: Qian Hong <qhong@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Qian Hong 2015-12-03 00:06:50 +08:00 committed by Alexandre Julliard
parent 3690fa0401
commit 6a03e618df
1 changed files with 41 additions and 16 deletions

View File

@ -1015,22 +1015,25 @@ static DWORD simd_fault_handler( EXCEPTION_RECORD *rec, EXCEPTION_REGISTRATION_R
context->Eip += 3; /* skip addps */ context->Eip += 3; /* skip addps */
return ExceptionContinueExecution; return ExceptionContinueExecution;
} }
else if ( *stage == 2 || *stage == 3 ) {
/* stage 2 - divide by zero fault */ /* stage 2 - divide by zero fault */
if( rec->ExceptionCode == EXCEPTION_ILLEGAL_INSTRUCTION) /* stage 3 - invalid operation fault */
skip("system doesn't support SIMD exceptions\n"); if( rec->ExceptionCode == EXCEPTION_ILLEGAL_INSTRUCTION)
else { skip("system doesn't support SIMD exceptions\n");
ok( rec->ExceptionCode == STATUS_FLOAT_MULTIPLE_TRAPS, else {
"exception code: %#x, should be %#x\n", ok( rec->ExceptionCode == STATUS_FLOAT_MULTIPLE_TRAPS,
rec->ExceptionCode, STATUS_FLOAT_MULTIPLE_TRAPS); "exception code: %#x, should be %#x\n",
ok( rec->NumberParameters == 1 || broken(is_wow64 && rec->NumberParameters == 2), rec->ExceptionCode, STATUS_FLOAT_MULTIPLE_TRAPS);
"# of params: %i, should be 1\n", ok( rec->NumberParameters == 1 || broken(is_wow64 && rec->NumberParameters == 2),
rec->NumberParameters); "# of params: %i, should be 1\n",
if( rec->NumberParameters == 1 ) rec->NumberParameters);
ok( rec->ExceptionInformation[0] == 0, "param #1: %lx, should be 0\n", rec->ExceptionInformation[0]); if( rec->NumberParameters == 1 )
ok( rec->ExceptionInformation[0] == 0, "param #1: %lx, should be 0\n", rec->ExceptionInformation[0]);
}
context->Eip += 3; /* skip divps */
} }
else
context->Eip += 3; /* skip divps */ ok(FALSE, "unexpected stage %x\n", *stage);
return ExceptionContinueExecution; return ExceptionContinueExecution;
} }
@ -1054,6 +1057,21 @@ static const BYTE simd_exception_test[] = {
0xc3, /* ret */ 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[] = { static const BYTE sse_check[] = {
0x0f, 0x58, 0xc8, /* addps %xmm0,%xmm1 */ 0x0f, 0x58, 0xc8, /* addps %xmm0,%xmm1 */
0xc3, /* ret */ 0xc3, /* ret */
@ -1077,7 +1095,14 @@ static void test_simd_exceptions(void)
got_exception = 0; got_exception = 0;
run_exception_test(simd_fault_handler, &stage, simd_exception_test, run_exception_test(simd_fault_handler, &stage, simd_exception_test,
sizeof(simd_exception_test), 0); 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 struct fpu_exception_info