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:
parent
3690fa0401
commit
6a03e618df
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue