2 * PROJECT: ReactOS api tests
3 * LICENSE: GPLv2+ - See COPYING in the top level directory
4 * PURPOSE: Test for SetUnhandledExceptionFilter
5 * PROGRAMMER: Mike "tamlin" Nordell
10 #include <xmmintrin.h>
13 * Keep these returning different values, to prevent compiler folding
14 * them into a single function, thereby voiding the test
16 LONG WINAPI
Filter1(LPEXCEPTION_POINTERS p
) { return 0; }
17 LONG WINAPI
Filter2(LPEXCEPTION_POINTERS p
) { return 1; }
21 * Verify that SetUnhandledExceptionFilter actually returns the
26 TestSetUnhandledExceptionFilter(VOID
)
28 LPTOP_LEVEL_EXCEPTION_FILTER p1
, p2
;
29 p1
= SetUnhandledExceptionFilter(Filter1
);
30 p2
= SetUnhandledExceptionFilter(Filter2
);
31 ok(p1
!= Filter1
, "SetUnhandledExceptionFilter returned what was set, not prev\n");
32 ok(p2
!= Filter2
, "SetUnhandledExceptionFilter returned what was set, not prev\n");
33 ok(p2
== Filter1
, "SetUnhandledExceptionFilter didn't return previous filter\n");
34 ok(p1
!= p2
, "SetUnhandledExceptionFilter seems to return random stuff\n");
36 p1
= SetUnhandledExceptionFilter(NULL
);
37 ok(p1
== Filter2
, "SetUnhandledExceptionFilter didn't return previous filter\n");
40 static LONG WINAPI
ExceptionFilterSSESupport(LPEXCEPTION_POINTERS exp
)
42 PEXCEPTION_RECORD rec
= exp
->ExceptionRecord
;
43 PCONTEXT ctx
= exp
->ContextRecord
;
45 trace("Exception raised while using SSE instructions.\n");
47 ok(rec
->ExceptionCode
== EXCEPTION_ILLEGAL_INSTRUCTION
, "Exception code is 0x%08x.\n", (unsigned int)rec
->ExceptionCode
);
49 if(rec
->ExceptionCode
!= EXCEPTION_ILLEGAL_INSTRUCTION
)
51 trace("Unexpected exception code, terminating!\n");
52 return EXCEPTION_EXECUTE_HANDLER
;
55 ok((ctx
->ContextFlags
& CONTEXT_CONTROL
) == CONTEXT_CONTROL
, "Context does not contain control register.\n");
59 #elif defined(_M_AMD64)
62 #error Architecture not handled
65 return EXCEPTION_CONTINUE_EXECUTION
;
68 static BOOL ExceptionCaught
= FALSE
;
70 static LONG WINAPI
ExceptionFilterSSEException(LPEXCEPTION_POINTERS exp
)
72 PEXCEPTION_RECORD rec
= exp
->ExceptionRecord
;
73 PCONTEXT ctx
= exp
->ContextRecord
;
75 ULONG ExpectedExceptionCode
= STATUS_FLOAT_DIVIDE_BY_ZERO
;
77 ULONG ExpectedExceptionCode
= STATUS_FLOAT_MULTIPLE_TRAPS
;
80 trace("Exception raised while dividing by 0.\n");
82 ok(rec
->ExceptionCode
== ExpectedExceptionCode
, "Exception code is 0x%08x.\n", (unsigned int)rec
->ExceptionCode
);
84 if(rec
->ExceptionCode
!= ExpectedExceptionCode
)
86 trace("Unexpected exception code, terminating!\n");
87 return EXCEPTION_EXECUTE_HANDLER
;
90 ok((ctx
->ContextFlags
& CONTEXT_CONTROL
) == CONTEXT_CONTROL
, "Context does not contain control register.\n");
92 ExceptionCaught
= TRUE
;
96 #elif defined(_M_AMD64)
99 #error Architecture not handled
102 return EXCEPTION_CONTINUE_EXECUTION
;
106 VOID
TestSSEExceptions(VOID
)
108 LPTOP_LEVEL_EXCEPTION_FILTER p
;
109 BOOL supportsSSE
= FALSE
;
112 /* Test SSE support for the CPU */
113 p
= SetUnhandledExceptionFilter(ExceptionFilterSSESupport
);
114 ok(p
== NULL
, "Previous filter should be NULL\n");
116 #if defined(_M_AMD64)
118 __m128 xmm
= { { 0 } };
119 xmm
= _mm_xor_ps(xmm
, xmm
);
120 if (!ExceptionCaught
) supportsSSE
= TRUE
;
131 "xorps %%xmm0, %%xmm0\n"
135 #endif /* _MSC_VER */
138 skip("CPU doesn't support SSE instructions.\n");
139 SetUnhandledExceptionFilter(NULL
);
142 /* Deliberately throw a divide by 0 exception */
143 p
= SetUnhandledExceptionFilter(ExceptionFilterSSEException
);
144 ok(p
== ExceptionFilterSSESupport
, "Unexpected old filter : 0x%p", p
);
146 /* Unmask divide by 0 exception */
148 _mm_setcsr(csr
& 0xFFFFFDFF);
150 /* We can't use _mm_div_ps, as it masks the exception before performing anything*/
151 #if defined(_MSC_VER)
152 #if defined(_M_AMD64)
154 __m128 xmm1
= { { 1., 1. } }, xmm2
= { { 0 } };
155 /* Wait, aren't exceptions masked? Yes, but actually no. */
156 xmm1
= _mm_div_ps(xmm1
, xmm2
);
157 if (!ExceptionCaught
) supportsSSE
= TRUE
;
179 "xorps %%xmm0, %%xmm0\n"
180 "pushl $0x3f800000\n"
181 "pushl $0x3f800000\n"
182 "pushl $0x3f800000\n"
183 "pushl $0x3f800000\n"
184 "movups (%%esp), %%xmm1\n"
187 "divps %%xmm0, %%xmm1\n"
193 #endif /* _MSC_VER */
198 ok(ExceptionCaught
, "The exception was not caught.\n");
200 p
= SetUnhandledExceptionFilter(NULL
);
201 ok(p
== ExceptionFilterSSEException
, "Unexpected old filter : 0x%p", p
);
204 START_TEST(SetUnhandledExceptionFilter
)
206 TestSetUnhandledExceptionFilter();