common_x86.c revision f49d345a51bb208fee19fc25762bcdb0e7f67174
1afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg/* 2afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg * Mesa 3-D graphics library 33a5ec72125075cbb59eda5c6ed6672524f4b48b3Brian Paul * Version: 6.5.1 4fc2427e81b1c648550d0368652d6a475df785027Gareth Hughes * 53a5ec72125075cbb59eda5c6ed6672524f4b48b3Brian Paul * Copyright (C) 1999-2006 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__) 39663a3e9ba700c832bfaea1f2131a37c5505d1c25George Sapountzis#include <linux/version.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 45f49d345a51bb208fee19fc25762bcdb0e7f67174Brad Smith#if defined(USE_SSE_ASM) && defined(__OpenBSD__) 46f49d345a51bb208fee19fc25762bcdb0e7f67174Brad Smith#include <sys/param.h> 47f49d345a51bb208fee19fc25762bcdb0e7f67174Brad Smith#include <sys/sysctl.h> 48f49d345a51bb208fee19fc25762bcdb0e7f67174Brad Smith#include <machine/cpu.h> 49f49d345a51bb208fee19fc25762bcdb0e7f67174Brad Smith#endif 50fc2427e81b1c648550d0368652d6a475df785027Gareth Hughes 51fc2427e81b1c648550d0368652d6a475df785027Gareth Hughes#include "common_x86_asm.h" 5262d821786c2b80f6b2a663f106a39e69116b02d5Brian Paul#include "imports.h" 53fc2427e81b1c648550d0368652d6a475df785027Gareth Hughes 54afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 55865322f931197c5c73c57b366b64300894565dabBrian Paulint _mesa_x86_cpu_features = 0; 56afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 57fc2427e81b1c648550d0368652d6a475df785027Gareth Hughes/* No reason for this to be public. 58fc2427e81b1c648550d0368652d6a475df785027Gareth Hughes */ 599b77fb7dab3fd4e4a9228e5c0609cc494aa01211Kendall Bennettextern GLuint _ASMAPI _mesa_x86_has_cpuid(void); 60c329e5a3d81a56437de4e19fec1de3eca2a1afb7Kendall Bennettextern void _ASMAPI _mesa_x86_cpuid(GLuint op, GLuint *reg_eax, GLuint *reg_ebx, GLuint *reg_ecx, GLuint *reg_edx); 619b77fb7dab3fd4e4a9228e5c0609cc494aa01211Kendall Bennettextern GLuint _ASMAPI _mesa_x86_cpuid_eax(GLuint op); 629b77fb7dab3fd4e4a9228e5c0609cc494aa01211Kendall Bennettextern GLuint _ASMAPI _mesa_x86_cpuid_ebx(GLuint op); 639b77fb7dab3fd4e4a9228e5c0609cc494aa01211Kendall Bennettextern GLuint _ASMAPI _mesa_x86_cpuid_ecx(GLuint op); 649b77fb7dab3fd4e4a9228e5c0609cc494aa01211Kendall Bennettextern GLuint _ASMAPI _mesa_x86_cpuid_edx(GLuint op); 65fc2427e81b1c648550d0368652d6a475df785027Gareth Hughes 66d8aec9b55b0180384e96cddff48fc48751bbc320Brian Paul 671b2fef5c28a40cd001598071e25b876ad4fccdd1Gareth Hughes#if defined(USE_SSE_ASM) 682ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes/* 692ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes * We must verify that the Streaming SIMD Extensions are truly supported 702ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes * on this processor before we go ahead and hook out the optimized code. 7181f67fc4e9621f08f46c8219f5ab5dc5c329b146Ian Romanick * 7281f67fc4e9621f08f46c8219f5ab5dc5c329b146Ian Romanick * However, I have been told by Alan Cox that all 2.4 (and later) Linux 7381f67fc4e9621f08f46c8219f5ab5dc5c329b146Ian Romanick * kernels provide full SSE support on all processors that expose SSE via 74663a3e9ba700c832bfaea1f2131a37c5505d1c25George Sapountzis * the CPUID mechanism. 752ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes */ 761b2fef5c28a40cd001598071e25b876ad4fccdd1Gareth Hughesextern void _mesa_test_os_sse_support( void ); 771b2fef5c28a40cd001598071e25b876ad4fccdd1Gareth Hughesextern void _mesa_test_os_sse_exception_support( void ); 782ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes 79eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul#if defined(WIN32) 80eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul#ifndef STATUS_FLOAT_MULTIPLE_TRAPS 81eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul# define STATUS_FLOAT_MULTIPLE_TRAPS (0xC00002B5L) 82eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul#endif 83eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paulstatic LONG WINAPI ExceptionFilter(LPEXCEPTION_POINTERS exp) 84eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul{ 85eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul PEXCEPTION_RECORD rec = exp->ExceptionRecord; 86eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul PCONTEXT ctx = exp->ContextRecord; 87eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul 88eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul if ( rec->ExceptionCode == EXCEPTION_ILLEGAL_INSTRUCTION ) { 893a5ec72125075cbb59eda5c6ed6672524f4b48b3Brian Paul _mesa_debug(NULL, "EXCEPTION_ILLEGAL_INSTRUCTION\n" ); 90eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul _mesa_x86_cpu_features &= ~(X86_FEATURE_XMM); 91eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul } else if ( rec->ExceptionCode == STATUS_FLOAT_MULTIPLE_TRAPS ) { 923a5ec72125075cbb59eda5c6ed6672524f4b48b3Brian Paul _mesa_debug(NULL, "STATUS_FLOAT_MULTIPLE_TRAPS\n"); 93eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul /* Windows seems to clear the exception flag itself, we just have to increment Eip */ 94eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul } else { 953a5ec72125075cbb59eda5c6ed6672524f4b48b3Brian Paul _mesa_debug(NULL, "UNEXPECTED EXCEPTION (0x%08x), terminating!\n" ); 96eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul return EXCEPTION_EXECUTE_HANDLER; 97eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul } 98eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul 99eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul if ( (ctx->ContextFlags & CONTEXT_CONTROL) != CONTEXT_CONTROL ) { 1003a5ec72125075cbb59eda5c6ed6672524f4b48b3Brian Paul _mesa_debug(NULL, "Context does not contain control registers, terminating!\n"); 101eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul return EXCEPTION_EXECUTE_HANDLER; 102eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul } 103eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul ctx->Eip += 3; 104eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul 105eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul return EXCEPTION_CONTINUE_EXECUTION; 106eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul} 107eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul#endif /* WIN32 */ 108eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul 109eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul 1101b2fef5c28a40cd001598071e25b876ad4fccdd1Gareth Hughesstatic void check_os_sse_support( void ) 1112ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes{ 11289f070b3bbb86204306857b8cf690abbd56a939dMichel Dänzer#if defined(__FreeBSD__) 113902d2faadf37a5627ab2cbcd8993825c8749ec82Brian Paul { 11438b317d508a2a3a4cc6d700ebca80c3b06c913e2Alan Hourihane int ret, enabled; 11538b317d508a2a3a4cc6d700ebca80c3b06c913e2Alan Hourihane unsigned int len; 116902d2faadf37a5627ab2cbcd8993825c8749ec82Brian Paul len = sizeof(enabled); 117902d2faadf37a5627ab2cbcd8993825c8749ec82Brian Paul ret = sysctlbyname("hw.instruction_sse", &enabled, &len, NULL, 0); 118902d2faadf37a5627ab2cbcd8993825c8749ec82Brian Paul if (ret || !enabled) 119902d2faadf37a5627ab2cbcd8993825c8749ec82Brian Paul _mesa_x86_cpu_features &= ~(X86_FEATURE_XMM); 120902d2faadf37a5627ab2cbcd8993825c8749ec82Brian Paul } 121ece7183ff1b1bba1ae8e41b143e2ccbc38376dc3Blair Sadewitz#elif defined (__NetBSD__) 122ece7183ff1b1bba1ae8e41b143e2ccbc38376dc3Blair Sadewitz { 123ece7183ff1b1bba1ae8e41b143e2ccbc38376dc3Blair Sadewitz int ret, enabled; 124ece7183ff1b1bba1ae8e41b143e2ccbc38376dc3Blair Sadewitz size_t len = sizeof(enabled); 125ece7183ff1b1bba1ae8e41b143e2ccbc38376dc3Blair Sadewitz ret = sysctlbyname("machdep.sse", &enabled, &len, (void *)NULL, 0); 126ece7183ff1b1bba1ae8e41b143e2ccbc38376dc3Blair Sadewitz if (ret || !enabled) 127ece7183ff1b1bba1ae8e41b143e2ccbc38376dc3Blair Sadewitz _mesa_x86_cpu_features &= ~(X86_FEATURE_XMM); 128ece7183ff1b1bba1ae8e41b143e2ccbc38376dc3Blair Sadewitz } 129f49d345a51bb208fee19fc25762bcdb0e7f67174Brad Smith#elif defined(__OpenBSD__) 130f49d345a51bb208fee19fc25762bcdb0e7f67174Brad Smith { 131f49d345a51bb208fee19fc25762bcdb0e7f67174Brad Smith int mib[2]; 132f49d345a51bb208fee19fc25762bcdb0e7f67174Brad Smith int ret, enabled; 133f49d345a51bb208fee19fc25762bcdb0e7f67174Brad Smith size_t len = sizeof(enabled); 134f49d345a51bb208fee19fc25762bcdb0e7f67174Brad Smith 135f49d345a51bb208fee19fc25762bcdb0e7f67174Brad Smith mib[0] = CTL_MACHDEP; 136f49d345a51bb208fee19fc25762bcdb0e7f67174Brad Smith mib[1] = CPU_SSE; 137f49d345a51bb208fee19fc25762bcdb0e7f67174Brad Smith 138f49d345a51bb208fee19fc25762bcdb0e7f67174Brad Smith ret = sysctl(mib, 2, &enabled, &len, NULL, 0); 139f49d345a51bb208fee19fc25762bcdb0e7f67174Brad Smith if (ret || !enabled) 140f49d345a51bb208fee19fc25762bcdb0e7f67174Brad Smith _mesa_x86_cpu_features &= ~(X86_FEATURE_XMM); 141f49d345a51bb208fee19fc25762bcdb0e7f67174Brad Smith } 142eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul#elif defined(WIN32) 143eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul LPTOP_LEVEL_EXCEPTION_FILTER oldFilter; 144eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul 145eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul /* Install our ExceptionFilter */ 146eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul oldFilter = SetUnhandledExceptionFilter( ExceptionFilter ); 147eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul 148eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul if ( cpu_has_xmm ) { 1493a5ec72125075cbb59eda5c6ed6672524f4b48b3Brian Paul _mesa_debug(NULL, "Testing OS support for SSE...\n"); 150eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul 151eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul _mesa_test_os_sse_support(); 152eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul 153eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul if ( cpu_has_xmm ) { 1543a5ec72125075cbb59eda5c6ed6672524f4b48b3Brian Paul _mesa_debug(NULL, "Yes.\n"); 155eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul } else { 1563a5ec72125075cbb59eda5c6ed6672524f4b48b3Brian Paul _mesa_debug(NULL, "No!\n"); 157eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul } 158eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul } 159eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul 160eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul if ( cpu_has_xmm ) { 1613a5ec72125075cbb59eda5c6ed6672524f4b48b3Brian Paul _mesa_debug(NULL, "Testing OS support for SSE unmasked exceptions...\n"); 162eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul 163eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul _mesa_test_os_sse_exception_support(); 164eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul 165eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul if ( cpu_has_xmm ) { 1663a5ec72125075cbb59eda5c6ed6672524f4b48b3Brian Paul _mesa_debug(NULL, "Yes.\n"); 167eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul } else { 1683a5ec72125075cbb59eda5c6ed6672524f4b48b3Brian Paul _mesa_debug(NULL, "No!\n"); 169eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul } 170eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul } 171eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul 172eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul /* Restore previous exception filter */ 173eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul SetUnhandledExceptionFilter( oldFilter ); 174eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul 175eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul if ( cpu_has_xmm ) { 1763a5ec72125075cbb59eda5c6ed6672524f4b48b3Brian Paul _mesa_debug(NULL, "Tests of OS support for SSE passed.\n"); 177eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul } else { 1783a5ec72125075cbb59eda5c6ed6672524f4b48b3Brian Paul _mesa_debug(NULL, "Tests of OS support for SSE failed!\n"); 179eaf2b170fffbd573ca8482a7dfa30af24f39a4a1Brian Paul } 1802ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes#else 181902d2faadf37a5627ab2cbcd8993825c8749ec82Brian Paul /* Do nothing on other platforms for now. 1822ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes */ 1833a5ec72125075cbb59eda5c6ed6672524f4b48b3Brian Paul _mesa_debug(NULL, "Not testing OS support for SSE, leaving enabled.\n"); 18489f070b3bbb86204306857b8cf690abbd56a939dMichel Dänzer#endif /* __FreeBSD__ */ 1852ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes} 1862ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes 1871b2fef5c28a40cd001598071e25b876ad4fccdd1Gareth Hughes#endif /* USE_SSE_ASM */ 1882ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes 189afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 19008836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paulvoid _mesa_init_all_x86_transform_asm( void ) 191afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg{ 192afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#ifdef USE_X86_ASM 193068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul _mesa_x86_cpu_features = 0; 194da54ffc852996f94dcf46b0cdc40c5ff12b55496Keith Whitwell 195068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul if (!_mesa_x86_has_cpuid()) { 1963a5ec72125075cbb59eda5c6ed6672524f4b48b3Brian Paul _mesa_debug(NULL, "CPUID not detected\n"); 197068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul } 198068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul else { 199068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul GLuint cpu_features; 200068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul GLuint cpu_ext_features; 201068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul GLuint cpu_ext_info; 202068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul char cpu_vendor[13]; 203068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul GLuint result; 204068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul 205068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul /* get vendor name */ 206068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul _mesa_x86_cpuid(0, &result, (GLuint *)(cpu_vendor + 0), (GLuint *)(cpu_vendor + 8), (GLuint *)(cpu_vendor + 4)); 207068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul cpu_vendor[12] = '\0'; 208068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul 2093a5ec72125075cbb59eda5c6ed6672524f4b48b3Brian Paul _mesa_debug(NULL, "CPU vendor: %s\n", cpu_vendor); 210068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul 211068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul /* get cpu features */ 212068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul cpu_features = _mesa_x86_cpuid_edx(1); 213068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul 214068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul if (cpu_features & X86_CPU_FPU) 215068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul _mesa_x86_cpu_features |= X86_FEATURE_FPU; 216068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul if (cpu_features & X86_CPU_CMOV) 217068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul _mesa_x86_cpu_features |= X86_FEATURE_CMOV; 218068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul 219068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul#ifdef USE_MMX_ASM 220068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul if (cpu_features & X86_CPU_MMX) 221068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul _mesa_x86_cpu_features |= X86_FEATURE_MMX; 222068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul#endif 223068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul 224068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul#ifdef USE_SSE_ASM 225068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul if (cpu_features & X86_CPU_XMM) 226068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul _mesa_x86_cpu_features |= X86_FEATURE_XMM; 227068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul if (cpu_features & X86_CPU_XMM2) 228068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul _mesa_x86_cpu_features |= X86_FEATURE_XMM2; 229068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul#endif 230068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul 231068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul /* query extended cpu features */ 232068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul if ((cpu_ext_info = _mesa_x86_cpuid_eax(0x80000000)) > 0x80000000) { 233068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul if (cpu_ext_info >= 0x80000001) { 234068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul 235068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul cpu_ext_features = _mesa_x86_cpuid_edx(0x80000001); 236068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul 237068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul if (cpu_features & X86_CPU_MMX) { 238068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul 239068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul#ifdef USE_3DNOW_ASM 240068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul if (cpu_ext_features & X86_CPUEXT_3DNOW) 241068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul _mesa_x86_cpu_features |= X86_FEATURE_3DNOW; 242068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul if (cpu_ext_features & X86_CPUEXT_3DNOW_EXT) 243068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul _mesa_x86_cpu_features |= X86_FEATURE_3DNOWEXT; 244068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul#endif 245068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul 246068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul#ifdef USE_MMX_ASM 247068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul if (cpu_ext_features & X86_CPUEXT_MMX_EXT) 248068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul _mesa_x86_cpu_features |= X86_FEATURE_MMXEXT; 249068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul#endif 250068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul } 251068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul } 252068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul 253068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul /* query cpu name */ 254068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul if (cpu_ext_info >= 0x80000002) { 255068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul GLuint ofs; 256068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul char cpu_name[49]; 257068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul for (ofs = 0; ofs < 3; ofs++) 258068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian 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)); 259068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul cpu_name[48] = '\0'; /* the name should be NULL terminated, but just to be sure */ 260068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul 2613a5ec72125075cbb59eda5c6ed6672524f4b48b3Brian Paul _mesa_debug(NULL, "CPU name: %s\n", cpu_name); 262068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul } 263068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul } 264068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul 265068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul } 266068a4812fc1d9e321aa65a91ceb8bc824bedc69aBrian Paul 26720c831bb899301642e3b7f808315459a6126e731Brian Paul if ( _mesa_getenv( "MESA_NO_ASM" ) ) { 268865322f931197c5c73c57b366b64300894565dabBrian Paul _mesa_x86_cpu_features = 0; 269afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg } 270afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 271865322f931197c5c73c57b366b64300894565dabBrian Paul if ( _mesa_x86_cpu_features ) { 27208836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul _mesa_init_x86_transform_asm(); 273da54ffc852996f94dcf46b0cdc40c5ff12b55496Keith Whitwell } 274afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 275afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#ifdef USE_MMX_ASM 276fc2427e81b1c648550d0368652d6a475df785027Gareth Hughes if ( cpu_has_mmx ) { 27720c831bb899301642e3b7f808315459a6126e731Brian Paul if ( _mesa_getenv( "MESA_NO_MMX" ) == 0 ) { 2783a5ec72125075cbb59eda5c6ed6672524f4b48b3Brian Paul _mesa_debug(NULL, "MMX cpu detected.\n"); 279afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg } else { 280865322f931197c5c73c57b366b64300894565dabBrian Paul _mesa_x86_cpu_features &= ~(X86_FEATURE_MMX); 281afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg } 282afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg } 283afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#endif 284afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 285afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#ifdef USE_3DNOW_ASM 286fc2427e81b1c648550d0368652d6a475df785027Gareth Hughes if ( cpu_has_3dnow ) { 28720c831bb899301642e3b7f808315459a6126e731Brian Paul if ( _mesa_getenv( "MESA_NO_3DNOW" ) == 0 ) { 2883a5ec72125075cbb59eda5c6ed6672524f4b48b3Brian Paul _mesa_debug(NULL, "3DNow! cpu detected.\n"); 28908836341788a9f9d638d9dc8328510ccd18ddeb5Brian Paul _mesa_init_3dnow_transform_asm(); 290afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg } else { 291865322f931197c5c73c57b366b64300894565dabBrian Paul _mesa_x86_cpu_features &= ~(X86_FEATURE_3DNOW); 292afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg } 293afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg } 294afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#endif 295afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 2961b2fef5c28a40cd001598071e25b876ad4fccdd1Gareth Hughes#ifdef USE_SSE_ASM 2972ac44e2509dff861d50239d3248c60bf08f3ed92Gareth Hughes if ( cpu_has_xmm ) { 29859c2e16e755c0cba78b27525681cd79456a2f496Daniel Borca if ( _mesa_getenv( "MESA_NO_SSE" ) == 0 ) { 2993a5ec72125075cbb59eda5c6ed6672524f4b48b3Brian Paul _mesa_debug(NULL, "SSE cpu detected.\n"); 30059c2e16e755c0cba78b27525681cd79456a2f496Daniel Borca if ( _mesa_getenv( "MESA_FORCE_SSE" ) == 0 ) { 30159c2e16e755c0cba78b27525681cd79456a2f496Daniel Borca check_os_sse_support(); 30259c2e16e755c0cba78b27525681cd79456a2f496Daniel Borca } 30359c2e16e755c0cba78b27525681cd79456a2f496Daniel Borca if ( cpu_has_xmm ) { 30459c2e16e755c0cba78b27525681cd79456a2f496Daniel Borca _mesa_init_sse_transform_asm(); 30559c2e16e755c0cba78b27525681cd79456a2f496Daniel Borca } 3066630e2be01f41fb3b0fdf815e00a82d8e980f116Andre Werthmann } else { 3073a5ec72125075cbb59eda5c6ed6672524f4b48b3Brian Paul _mesa_debug(NULL, "SSE cpu detected, but switched off by user.\n"); 308865322f931197c5c73c57b366b64300894565dabBrian Paul _mesa_x86_cpu_features &= ~(X86_FEATURE_XMM); 3096630e2be01f41fb3b0fdf815e00a82d8e980f116Andre Werthmann } 3106630e2be01f41fb3b0fdf815e00a82d8e980f116Andre Werthmann } 3116630e2be01f41fb3b0fdf815e00a82d8e980f116Andre Werthmann#endif 312afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg#endif 313afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg} 314afb833d4e89c312460a4ab9ed6a7a8ca4ebbfe1cjtg 315