common_x86.c revision 59c2e16e755c0cba78b27525681cd79456a2f496
1afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg/*
2afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * Mesa 3-D graphics library
320c831bb899301642e3b7f808315459a6126e731Brian Paul * Version:  6.0.1
4fc2427e81b1c648550d0368652d6a475df785027Gareth Hughes *
520c831bb899301642e3b7f808315459a6126e731Brian Paul * Copyright (C) 1999-2004  Brian Paul   All Rights Reserved.
6fc2427e81b1c648550d0368652d6a475df785027Gareth Hughes *
7afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * Permission is hereby granted, free of charge, to any person obtaining a
8afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * copy of this software and associated documentation files (the "Software"),
9afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * to deal in the Software without restriction, including without limitation
10afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * and/or sell copies of the Software, and to permit persons to whom the
12afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * Software is furnished to do so, subject to the following conditions:
13fc2427e81b1c648550d0368652d6a475df785027Gareth Hughes *
14afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * The above copyright notice and this permission notice shall be included
15afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * in all copies or substantial portions of the Software.
16fc2427e81b1c648550d0368652d6a475df785027Gareth Hughes *
17afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg */
24afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
2581f67fc4e9621f08f46c8219f5ab5dc5c329b146Ian Romanick/**
2681f67fc4e9621f08f46c8219f5ab5dc5c329b146Ian Romanick * \file common_x86.c
2781f67fc4e9621f08f46c8219f5ab5dc5c329b146Ian Romanick *
28fc2427e81b1c648550d0368652d6a475df785027Gareth Hughes * Check CPU capabilities & initialize optimized funtions for this particular
29fc2427e81b1c648550d0368652d6a475df785027Gareth Hughes * processor.
30afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg *
3181f67fc4e9621f08f46c8219f5ab5dc5c329b146Ian Romanick * Changed by Andre Werthmann for using the new SSE functions.
3281f67fc4e9621f08f46c8219f5ab5dc5c329b146Ian Romanick *
3381f67fc4e9621f08f46c8219f5ab5dc5c329b146Ian Romanick * \author Holger Waechtler <holger@akaflieg.extern.tu-berlin.de>
3481f67fc4e9621f08f46c8219f5ab5dc5c329b146Ian Romanick * \author Andre Werthmann <wertmann@cs.uni-potsdam.de>
35afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg */
36afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
3720c831bb899301642e3b7f808315459a6126e731Brian Paul/* XXX these includes should probably go into imports.h or glheader.h */
381b2fef5c28a40cd001598071e25b876ad4fccdd1Gareth Hughes#if defined(USE_SSE_ASM) && defined(__linux__)
392ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes#include <signal.h>
402ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes#endif
41902d2faadf37a5627ab2cbcd8993825c8749ec82Brian Paul#if defined(USE_SSE_ASM) && defined(__FreeBSD__)
42902d2faadf37a5627ab2cbcd8993825c8749ec82Brian Paul#include <sys/types.h>
43902d2faadf37a5627ab2cbcd8993825c8749ec82Brian Paul#include <sys/sysctl.h>
44902d2faadf37a5627ab2cbcd8993825c8749ec82Brian Paul#endif
45fc2427e81b1c648550d0368652d6a475df785027Gareth Hughes
46fc2427e81b1c648550d0368652d6a475df785027Gareth Hughes#include "common_x86_asm.h"
4762d821786c2b80f6b2a663f106a39e69116b02d5Brian Paul#include "imports.h"
48fc2427e81b1c648550d0368652d6a475df785027Gareth Hughes
49afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
50865322f931197c5c73c57b366b64300894565dabBrian Paulint _mesa_x86_cpu_features = 0;
51afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
52fc2427e81b1c648550d0368652d6a475df785027Gareth Hughes/* No reason for this to be public.
53fc2427e81b1c648550d0368652d6a475df785027Gareth Hughes */
549b77fb7dab3fd4e4a9228e5c0609cc494aa01211Kendall Bennettextern GLuint	_ASMAPI _mesa_x86_has_cpuid(void);
55c329e5a3d81a56437de4e19fec1de3eca2a1afb7Kendall Bennettextern void	_ASMAPI _mesa_x86_cpuid(GLuint op, GLuint *reg_eax, GLuint *reg_ebx, GLuint *reg_ecx, GLuint *reg_edx);
569b77fb7dab3fd4e4a9228e5c0609cc494aa01211Kendall Bennettextern GLuint	_ASMAPI _mesa_x86_cpuid_eax(GLuint op);
579b77fb7dab3fd4e4a9228e5c0609cc494aa01211Kendall Bennettextern GLuint	_ASMAPI _mesa_x86_cpuid_ebx(GLuint op);
589b77fb7dab3fd4e4a9228e5c0609cc494aa01211Kendall Bennettextern GLuint	_ASMAPI _mesa_x86_cpuid_ecx(GLuint op);
599b77fb7dab3fd4e4a9228e5c0609cc494aa01211Kendall Bennettextern GLuint	_ASMAPI _mesa_x86_cpuid_edx(GLuint op);
60fc2427e81b1c648550d0368652d6a475df785027Gareth Hughes
61fc2427e81b1c648550d0368652d6a475df785027Gareth Hughesstatic void message( const char *msg )
62d8aec9b55b0180384e96cddff48fc48751bbc320Brian Paul{
632ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes   GLboolean debug;
642ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes#ifdef DEBUG
652ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes   debug = GL_TRUE;
662ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes#else
6720c831bb899301642e3b7f808315459a6126e731Brian Paul   if ( _mesa_getenv( "MESA_DEBUG" ) ) {
682ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes      debug = GL_TRUE;
692ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes   } else {
702ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes      debug = GL_FALSE;
712ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes   }
722ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes#endif
732ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes   if ( debug ) {
742ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes      fprintf( stderr, "%s", msg );
75fc2427e81b1c648550d0368652d6a475df785027Gareth Hughes   }
76d8aec9b55b0180384e96cddff48fc48751bbc320Brian Paul}
77d8aec9b55b0180384e96cddff48fc48751bbc320Brian Paul
781b2fef5c28a40cd001598071e25b876ad4fccdd1Gareth Hughes#if defined(USE_SSE_ASM)
792ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes/*
802ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes * We must verify that the Streaming SIMD Extensions are truly supported
812ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes * on this processor before we go ahead and hook out the optimized code.
822ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes * Unfortunately, the CPUID bit isn't enough, as the OS must set the
832ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes * OSFXSR bit in CR4 if it supports the extended FPU save and restore
842ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes * required to use SSE.  Unfortunately, we can't just go ahead and read
852ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes * this register, as only the kernel can do that.  Similarly, we must
862ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes * verify that the OSXMMEXCPT bit in CR4 has been set by the OS,
872ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes * signifying that it supports unmasked SIMD FPU exceptions.  If we take
882ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes * an unmasked exception and the OS doesn't correctly support them, the
892ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes * best we'll get is a SIGILL and the worst we'll get is an infinite
902ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes * loop in the signal delivery from the kernel as we can't interact with
912ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes * the SIMD FPU state to clear the exception bits.  Either way, this is
922ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes * not good.
9381f67fc4e9621f08f46c8219f5ab5dc5c329b146Ian Romanick *
9481f67fc4e9621f08f46c8219f5ab5dc5c329b146Ian Romanick * However, I have been told by Alan Cox that all 2.4 (and later) Linux
9581f67fc4e9621f08f46c8219f5ab5dc5c329b146Ian Romanick * kernels provide full SSE support on all processors that expose SSE via
9681f67fc4e9621f08f46c8219f5ab5dc5c329b146Ian Romanick * the CPUID mechanism.  It just so happens that this is the exact set of
9781f67fc4e9621f08f46c8219f5ab5dc5c329b146Ian Romanick * kernels supported DRI.  Therefore, when building for DRI the funky SSE
9881f67fc4e9621f08f46c8219f5ab5dc5c329b146Ian Romanick * exception test is omitted.
992ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes */
1002ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes
1011b2fef5c28a40cd001598071e25b876ad4fccdd1Gareth Hughesextern void _mesa_test_os_sse_support( void );
1021b2fef5c28a40cd001598071e25b876ad4fccdd1Gareth Hughesextern void _mesa_test_os_sse_exception_support( void );
1032ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes
10481f67fc4e9621f08f46c8219f5ab5dc5c329b146Ian Romanick#if defined(__linux__) && defined(_POSIX_SOURCE) && defined(X86_FXSR_MAGIC) \
10581f67fc4e9621f08f46c8219f5ab5dc5c329b146Ian Romanick   && !defined(DRI_NEW_INTERFACE_ONLY)
1062ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughesstatic void sigill_handler( int signal, struct sigcontext sc )
1072ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes{
1082ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes   message( "SIGILL, " );
1092ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes
1102ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes   /* Both the "xorps %%xmm0,%%xmm0" and "divps %xmm0,%%xmm1"
1112ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes    * instructions are 3 bytes long.  We must increment the instruction
1122ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes    * pointer manually to avoid repeated execution of the offending
1132ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes    * instruction.
1142ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes    *
1152ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes    * If the SIGILL is caused by a divide-by-zero when unmasked
1162ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes    * exceptions aren't supported, the SIMD FPU status and control
1172ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes    * word will be restored at the end of the test, so we don't need
1182ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes    * to worry about doing it here.  Besides, we may not be able to...
1192ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes    */
1202ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes   sc.eip += 3;
1212ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes
122865322f931197c5c73c57b366b64300894565dabBrian Paul   _mesa_x86_cpu_features &= ~(X86_FEATURE_XMM);
1232ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes}
1242ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes
1252ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughesstatic void sigfpe_handler( int signal, struct sigcontext sc )
1262ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes{
1272ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes   message( "SIGFPE, " );
1282ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes
1292ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes   if ( sc.fpstate->magic != 0xffff ) {
1302ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes      /* Our signal context has the extended FPU state, so reset the
1312ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes       * divide-by-zero exception mask and clear the divide-by-zero
1322ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes       * exception bit.
1332ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes       */
1342ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes      sc.fpstate->mxcsr |= 0x00000200;
1352ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes      sc.fpstate->mxcsr &= 0xfffffffb;
1362ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes   } else {
1372ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes      /* If we ever get here, we're completely hosed.
1382ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes       */
1392ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes      message( "\n\n" );
14008836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul      _mesa_problem( NULL, "SSE enabling test failed badly!" );
1412ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes   }
1422ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes}
143a5455bb374571833080fcbd6728edcba13d45b38Brian Paul#endif /* __linux__ && _POSIX_SOURCE && X86_FXSR_MAGIC */
1442ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes
145eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul#if defined(WIN32)
146eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul#ifndef STATUS_FLOAT_MULTIPLE_TRAPS
147eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul# define STATUS_FLOAT_MULTIPLE_TRAPS (0xC00002B5L)
148eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul#endif
149eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paulstatic LONG WINAPI ExceptionFilter(LPEXCEPTION_POINTERS exp)
150eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul{
151eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul   PEXCEPTION_RECORD rec = exp->ExceptionRecord;
152eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul   PCONTEXT ctx = exp->ContextRecord;
153eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul
154eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul   if ( rec->ExceptionCode == EXCEPTION_ILLEGAL_INSTRUCTION ) {
155eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul      message( "EXCEPTION_ILLEGAL_INSTRUCTION, " );
156eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul      _mesa_x86_cpu_features &= ~(X86_FEATURE_XMM);
157eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul   } else if ( rec->ExceptionCode == STATUS_FLOAT_MULTIPLE_TRAPS ) {
158eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul      message( "STATUS_FLOAT_MULTIPLE_TRAPS, " );
159eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul      /* Windows seems to clear the exception flag itself, we just have to increment Eip */
160eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul   } else {
161eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul      message( "UNEXPECTED EXCEPTION (0x%08x), terminating!" );
162eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul      return EXCEPTION_EXECUTE_HANDLER;
163eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul   }
164eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul
165eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul   if ( (ctx->ContextFlags & CONTEXT_CONTROL) != CONTEXT_CONTROL ) {
166eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul      message( "Context does not contain control registers, terminating!" );
167eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul      return EXCEPTION_EXECUTE_HANDLER;
168eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul   }
169eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul   ctx->Eip += 3;
170eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul
171eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul   return EXCEPTION_CONTINUE_EXECUTION;
172eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul}
173eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul#endif /* WIN32 */
174eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul
175eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul
1762ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes/* If we're running on a processor that can do SSE, let's see if we
1772ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes * are allowed to or not.  This will catch 2.4.0 or later kernels that
1782ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes * haven't been configured for a Pentium III but are running on one,
1792ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes * and RedHat patched 2.2 kernels that have broken exception handling
1802ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes * support for user space apps that do SSE.
1812ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes *
1822ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes * GH: Isn't this just awful?
1832ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes */
1841b2fef5c28a40cd001598071e25b876ad4fccdd1Gareth Hughesstatic void check_os_sse_support( void )
1852ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes{
18681f67fc4e9621f08f46c8219f5ab5dc5c329b146Ian Romanick#if defined(__linux__) && !defined(DRI_NEW_INTERFACE_ONLY)
187a5455bb374571833080fcbd6728edcba13d45b38Brian Paul#if defined(_POSIX_SOURCE) && defined(X86_FXSR_MAGIC)
1882ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes   struct sigaction saved_sigill;
1892ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes   struct sigaction saved_sigfpe;
1902ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes
1912ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes   /* Save the original signal handlers.
1922ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes    */
1932ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes   sigaction( SIGILL, NULL, &saved_sigill );
1942ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes   sigaction( SIGFPE, NULL, &saved_sigfpe );
1952ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes
1962ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes   signal( SIGILL, (void (*)(int))sigill_handler );
1972ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes   signal( SIGFPE, (void (*)(int))sigfpe_handler );
1982ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes
1992ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes   /* Emulate test for OSFXSR in CR4.  The OS will set this bit if it
2002ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes    * supports the extended FPU save and restore required for SSE.  If
2012ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes    * we execute an SSE instruction on a PIII and get a SIGILL, the OS
2022ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes    * doesn't support Streaming SIMD Exceptions, even if the processor
2032ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes    * does.
2042ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes    */
2052ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes   if ( cpu_has_xmm ) {
2062ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes      message( "Testing OS support for SSE... " );
2072ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes
2081b2fef5c28a40cd001598071e25b876ad4fccdd1Gareth Hughes      _mesa_test_os_sse_support();
2092ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes
2102ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes      if ( cpu_has_xmm ) {
2112ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes	 message( "yes.\n" );
2122ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes      } else {
2132ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes	 message( "no!\n" );
2142ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes      }
2152ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes   }
2162ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes
2172ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes   /* Emulate test for OSXMMEXCPT in CR4.  The OS will set this bit if
2182ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes    * it supports unmasked SIMD FPU exceptions.  If we unmask the
2192ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes    * exceptions, do a SIMD divide-by-zero and get a SIGILL, the OS
2202ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes    * doesn't support unmasked SIMD FPU exceptions.  If we get a SIGFPE
2212ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes    * as expected, we're okay but we need to clean up after it.
2222ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes    *
2232ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes    * Are we being too stringent in our requirement that the OS support
2242ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes    * unmasked exceptions?  Certain RedHat 2.2 kernels enable SSE by
2252ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes    * setting CR4.OSFXSR but don't support unmasked exceptions.  Win98
2262ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes    * doesn't even support them.  We at least know the user-space SSE
2272ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes    * support is good in kernels that do support unmasked exceptions,
2282ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes    * and therefore to be safe I'm going to leave this test in here.
2292ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes    */
2302ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes   if ( cpu_has_xmm ) {
2312ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes      message( "Testing OS support for SSE unmasked exceptions... " );
2322ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes
2331b2fef5c28a40cd001598071e25b876ad4fccdd1Gareth Hughes      _mesa_test_os_sse_exception_support();
2342ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes
2352ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes      if ( cpu_has_xmm ) {
2362ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes	 message( "yes.\n" );
2372ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes      } else {
2382ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes	 message( "no!\n" );
2392ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes      }
2402ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes   }
2412ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes
2422ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes   /* Restore the original signal handlers.
2432ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes    */
2442ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes   sigaction( SIGILL, &saved_sigill, NULL );
2452ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes   sigaction( SIGFPE, &saved_sigfpe, NULL );
2462ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes
2472ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes   /* If we've gotten to here and the XMM CPUID bit is still set, we're
2482ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes    * safe to go ahead and hook out the SSE code throughout Mesa.
2492ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes    */
2502ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes   if ( cpu_has_xmm ) {
2512ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes      message( "Tests of OS support for SSE passed.\n" );
2522ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes   } else {
2532ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes      message( "Tests of OS support for SSE failed!\n" );
2542ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes   }
2552ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes#else
2562ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes   /* We can't use POSIX signal handling to test the availability of
2572ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes    * SSE, so we disable it by default.
2582ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes    */
2592ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes   message( "Cannot test OS support for SSE, disabling to be safe.\n" );
260865322f931197c5c73c57b366b64300894565dabBrian Paul   _mesa_x86_cpu_features &= ~(X86_FEATURE_XMM);
261a5455bb374571833080fcbd6728edcba13d45b38Brian Paul#endif /* _POSIX_SOURCE && X86_FXSR_MAGIC */
262902d2faadf37a5627ab2cbcd8993825c8749ec82Brian Paul#elif defined(__FreeBSD__)
263902d2faadf37a5627ab2cbcd8993825c8749ec82Brian Paul   {
26438b317d508a2a3a4cc6d700ebca80c3b06c913e2Alan Hourihane      int ret, enabled;
26538b317d508a2a3a4cc6d700ebca80c3b06c913e2Alan Hourihane      unsigned int len;
266902d2faadf37a5627ab2cbcd8993825c8749ec82Brian Paul      len = sizeof(enabled);
267902d2faadf37a5627ab2cbcd8993825c8749ec82Brian Paul      ret = sysctlbyname("hw.instruction_sse", &enabled, &len, NULL, 0);
268902d2faadf37a5627ab2cbcd8993825c8749ec82Brian Paul      if (ret || !enabled)
269902d2faadf37a5627ab2cbcd8993825c8749ec82Brian Paul         _mesa_x86_cpu_features &= ~(X86_FEATURE_XMM);
270902d2faadf37a5627ab2cbcd8993825c8749ec82Brian Paul   }
271eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul#elif defined(WIN32)
272eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul   LPTOP_LEVEL_EXCEPTION_FILTER oldFilter;
273eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul
274eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul   /* Install our ExceptionFilter */
275eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul   oldFilter = SetUnhandledExceptionFilter( ExceptionFilter );
276eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul
277eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul   if ( cpu_has_xmm ) {
278eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul      message( "Testing OS support for SSE... " );
279eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul
280eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul      _mesa_test_os_sse_support();
281eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul
282eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul      if ( cpu_has_xmm ) {
283eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul	 message( "yes.\n" );
284eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul      } else {
285eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul	 message( "no!\n" );
286eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul      }
287eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul   }
288eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul
289eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul   if ( cpu_has_xmm ) {
290eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul      message( "Testing OS support for SSE unmasked exceptions... " );
291eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul
292eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul      _mesa_test_os_sse_exception_support();
293eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul
294eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul      if ( cpu_has_xmm ) {
295eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul	 message( "yes.\n" );
296eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul      } else {
297eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul	 message( "no!\n" );
298eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul      }
299eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul   }
300eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul
301eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul   /* Restore previous exception filter */
302eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul   SetUnhandledExceptionFilter( oldFilter );
303eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul
304eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul   if ( cpu_has_xmm ) {
305eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul      message( "Tests of OS support for SSE passed.\n" );
306eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul   } else {
307eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul      message( "Tests of OS support for SSE failed!\n" );
308eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul   }
3092ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes#else
310902d2faadf37a5627ab2cbcd8993825c8749ec82Brian Paul   /* Do nothing on other platforms for now.
3112ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes    */
3122ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes   message( "Not testing OS support for SSE, leaving enabled.\n" );
3132ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes#endif /* __linux__ */
3142ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes}
3152ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes
3161b2fef5c28a40cd001598071e25b876ad4fccdd1Gareth Hughes#endif /* USE_SSE_ASM */
3172ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes
318afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
31908836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paulvoid _mesa_init_all_x86_transform_asm( void )
320afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{
3214e9676fb13f60ecdbc247b120031f18cd3febcb0Brian Paul   (void) message; /* silence warning */
322afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#ifdef USE_X86_ASM
323068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul   _mesa_x86_cpu_features = 0;
324da54ffc852996f94dcf46b0cdc40c5ff12b55496Keith Whitwell
325068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul   if (!_mesa_x86_has_cpuid()) {
326068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul       message("CPUID not detected");
327068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul   }
328068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul   else {
329068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul       GLuint cpu_features;
330068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul       GLuint cpu_ext_features;
331068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul       GLuint cpu_ext_info;
332068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul       char cpu_vendor[13];
333068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul       GLuint result;
334068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul
335068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul       /* get vendor name */
336068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul       _mesa_x86_cpuid(0, &result, (GLuint *)(cpu_vendor + 0), (GLuint *)(cpu_vendor + 8), (GLuint *)(cpu_vendor + 4));
337068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul       cpu_vendor[12] = '\0';
338068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul
339068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul       message("cpu vendor: ");
340068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul       message(cpu_vendor);
341068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul       message("\n");
342068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul
343068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul       /* get cpu features */
344068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul       cpu_features = _mesa_x86_cpuid_edx(1);
345068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul
346068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul       if (cpu_features & X86_CPU_FPU)
347068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul	   _mesa_x86_cpu_features |= X86_FEATURE_FPU;
348068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul       if (cpu_features & X86_CPU_CMOV)
349068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul	   _mesa_x86_cpu_features |= X86_FEATURE_CMOV;
350068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul
351068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul#ifdef USE_MMX_ASM
352068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul       if (cpu_features & X86_CPU_MMX)
353068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul	   _mesa_x86_cpu_features |= X86_FEATURE_MMX;
354068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul#endif
355068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul
356068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul#ifdef USE_SSE_ASM
357068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul       if (cpu_features & X86_CPU_XMM)
358068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul	   _mesa_x86_cpu_features |= X86_FEATURE_XMM;
359068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul       if (cpu_features & X86_CPU_XMM2)
360068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul	   _mesa_x86_cpu_features |= X86_FEATURE_XMM2;
361068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul#endif
362068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul
363068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul       /* query extended cpu features */
364068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul       if ((cpu_ext_info = _mesa_x86_cpuid_eax(0x80000000)) > 0x80000000) {
365068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul	   if (cpu_ext_info >= 0x80000001) {
366068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul
367068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul	       cpu_ext_features = _mesa_x86_cpuid_edx(0x80000001);
368068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul
369068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul	       if (cpu_features & X86_CPU_MMX) {
370068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul
371068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul#ifdef USE_3DNOW_ASM
372068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul		   if (cpu_ext_features & X86_CPUEXT_3DNOW)
373068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul		       _mesa_x86_cpu_features |= X86_FEATURE_3DNOW;
374068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul		   if (cpu_ext_features & X86_CPUEXT_3DNOW_EXT)
375068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul		       _mesa_x86_cpu_features |= X86_FEATURE_3DNOWEXT;
376068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul#endif
377068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul
378068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul#ifdef USE_MMX_ASM
379068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul		   if (cpu_ext_features & X86_CPUEXT_MMX_EXT)
380068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul		       _mesa_x86_cpu_features |= X86_FEATURE_MMXEXT;
381068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul#endif
382068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul	       }
383068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul	   }
384068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul
385068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul	   /* query cpu name */
386068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul	   if (cpu_ext_info >= 0x80000002) {
387068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul	       GLuint ofs;
388068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul	       char cpu_name[49];
389068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul	       for (ofs = 0; ofs < 3; ofs++)
390068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul		   _mesa_x86_cpuid(0x80000002+ofs, (GLuint *)(cpu_name + (16*ofs)+0), (GLuint *)(cpu_name + (16*ofs)+4), (GLuint *)(cpu_name + (16*ofs)+8), (GLuint *)(cpu_name + (16*ofs)+12));
391068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul	       cpu_name[48] = '\0'; /* the name should be NULL terminated, but just to be sure */
392068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul
393068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul	       message("cpu name: ");
394068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul	       message(cpu_name);
395068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul	       message("\n");
396068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul	   }
397068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul       }
398068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul
399068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul   }
400068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul
40120c831bb899301642e3b7f808315459a6126e731Brian Paul   if ( _mesa_getenv( "MESA_NO_ASM" ) ) {
402865322f931197c5c73c57b366b64300894565dabBrian Paul      _mesa_x86_cpu_features = 0;
403afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
404afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
405865322f931197c5c73c57b366b64300894565dabBrian Paul   if ( _mesa_x86_cpu_features ) {
40608836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul      _mesa_init_x86_transform_asm();
407da54ffc852996f94dcf46b0cdc40c5ff12b55496Keith Whitwell   }
408afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
409afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#ifdef USE_MMX_ASM
410fc2427e81b1c648550d0368652d6a475df785027Gareth Hughes   if ( cpu_has_mmx ) {
41120c831bb899301642e3b7f808315459a6126e731Brian Paul      if ( _mesa_getenv( "MESA_NO_MMX" ) == 0 ) {
4122ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes         message( "MMX cpu detected.\n" );
413afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      } else {
414865322f931197c5c73c57b366b64300894565dabBrian Paul         _mesa_x86_cpu_features &= ~(X86_FEATURE_MMX);
415afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
416afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
417afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#endif
418afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
419afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#ifdef USE_3DNOW_ASM
420fc2427e81b1c648550d0368652d6a475df785027Gareth Hughes   if ( cpu_has_3dnow ) {
42120c831bb899301642e3b7f808315459a6126e731Brian Paul      if ( _mesa_getenv( "MESA_NO_3DNOW" ) == 0 ) {
4222ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes         message( "3DNow! cpu detected.\n" );
42308836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul         _mesa_init_3dnow_transform_asm();
424afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      } else {
425865322f931197c5c73c57b366b64300894565dabBrian Paul         _mesa_x86_cpu_features &= ~(X86_FEATURE_3DNOW);
426afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg      }
427afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg   }
428afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#endif
429afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
4301b2fef5c28a40cd001598071e25b876ad4fccdd1Gareth Hughes#ifdef USE_SSE_ASM
4312ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes   if ( cpu_has_xmm ) {
43259c2e16e755c0cba78b27525681cd79456a2f496Daniel Borca      if ( _mesa_getenv( "MESA_NO_SSE" ) == 0 ) {
4331b2fef5c28a40cd001598071e25b876ad4fccdd1Gareth Hughes         message( "SSE cpu detected.\n" );
43459c2e16e755c0cba78b27525681cd79456a2f496Daniel Borca         if ( _mesa_getenv( "MESA_FORCE_SSE" ) == 0 ) {
43559c2e16e755c0cba78b27525681cd79456a2f496Daniel Borca            check_os_sse_support();
43659c2e16e755c0cba78b27525681cd79456a2f496Daniel Borca         }
43759c2e16e755c0cba78b27525681cd79456a2f496Daniel Borca         if ( cpu_has_xmm ) {
43859c2e16e755c0cba78b27525681cd79456a2f496Daniel Borca            _mesa_init_sse_transform_asm();
43959c2e16e755c0cba78b27525681cd79456a2f496Daniel Borca         }
4406630e2be01f41fb3b0fdf815e00a82d8e980f116Andre Werthmann      } else {
44159c2e16e755c0cba78b27525681cd79456a2f496Daniel Borca         message( "SSE cpu detected, but switched off by user.\n" );
442865322f931197c5c73c57b366b64300894565dabBrian Paul         _mesa_x86_cpu_features &= ~(X86_FEATURE_XMM);
4436630e2be01f41fb3b0fdf815e00a82d8e980f116Andre Werthmann      }
4446630e2be01f41fb3b0fdf815e00a82d8e980f116Andre Werthmann   }
4456630e2be01f41fb3b0fdf815e00a82d8e980f116Andre Werthmann#endif
446afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#endif
447afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg}
448afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg
449