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;
}
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 */
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