diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/mesa/x86/common_x86.c | 69 | 
1 files changed, 69 insertions, 0 deletions
| diff --git a/src/mesa/x86/common_x86.c b/src/mesa/x86/common_x86.c index b3e1401b8a..d5b87e8156 100644 --- a/src/mesa/x86/common_x86.c +++ b/src/mesa/x86/common_x86.c @@ -142,6 +142,37 @@ static void sigfpe_handler( int signal, struct sigcontext sc )  }  #endif /* __linux__ && _POSIX_SOURCE && X86_FXSR_MAGIC */ +#if defined(WIN32) +#ifndef STATUS_FLOAT_MULTIPLE_TRAPS +# define STATUS_FLOAT_MULTIPLE_TRAPS (0xC00002B5L) +#endif +static LONG WINAPI ExceptionFilter(LPEXCEPTION_POINTERS exp) +{ +   PEXCEPTION_RECORD rec = exp->ExceptionRecord; +   PCONTEXT ctx = exp->ContextRecord; + +   if ( rec->ExceptionCode == EXCEPTION_ILLEGAL_INSTRUCTION ) { +      message( "EXCEPTION_ILLEGAL_INSTRUCTION, " ); +      _mesa_x86_cpu_features &= ~(X86_FEATURE_XMM); +   } else if ( rec->ExceptionCode == STATUS_FLOAT_MULTIPLE_TRAPS ) { +      message( "STATUS_FLOAT_MULTIPLE_TRAPS, " ); +      /* Windows seems to clear the exception flag itself, we just have to increment Eip */ +   } else { +      message( "UNEXPECTED EXCEPTION (0x%08x), terminating!" ); +      return EXCEPTION_EXECUTE_HANDLER; +   } + +   if ( (ctx->ContextFlags & CONTEXT_CONTROL) != CONTEXT_CONTROL ) { +      message( "Context does not contain control registers, terminating!" ); +      return EXCEPTION_EXECUTE_HANDLER; +   } +   ctx->Eip += 3; + +   return EXCEPTION_CONTINUE_EXECUTION; +} +#endif /* WIN32 */ + +  /* If we're running on a processor that can do SSE, let's see if we   * are allowed to or not.  This will catch 2.4.0 or later kernels that   * haven't been configured for a Pentium III but are running on one, @@ -237,6 +268,44 @@ static void check_os_sse_support( void )        if (ret || !enabled)           _mesa_x86_cpu_features &= ~(X86_FEATURE_XMM);     } +#elif defined(WIN32) +   LPTOP_LEVEL_EXCEPTION_FILTER oldFilter; +    +   /* Install our ExceptionFilter */ +   oldFilter = SetUnhandledExceptionFilter( ExceptionFilter ); +    +   if ( cpu_has_xmm ) { +      message( "Testing OS support for SSE... " ); + +      _mesa_test_os_sse_support(); + +      if ( cpu_has_xmm ) { +	 message( "yes.\n" ); +      } else { +	 message( "no!\n" ); +      } +   } + +   if ( cpu_has_xmm ) { +      message( "Testing OS support for SSE unmasked exceptions... " ); + +      _mesa_test_os_sse_exception_support(); + +      if ( cpu_has_xmm ) { +	 message( "yes.\n" ); +      } else { +	 message( "no!\n" ); +      } +   } + +   /* Restore previous exception filter */ +   SetUnhandledExceptionFilter( oldFilter ); + +   if ( cpu_has_xmm ) { +      message( "Tests of OS support for SSE passed.\n" ); +   } else { +      message( "Tests of OS support for SSE failed!\n" ); +   }  #else     /* Do nothing on other platforms for now.      */ | 
