1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* 2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Mesa 3-D graphics library 3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Version: 6.5.1 4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. 6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a 8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the "Software"), 9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to deal in the Software without restriction, including without limitation 10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * and/or sell copies of the Software, and to permit persons to whom the 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software is furnished to do so, subject to the following conditions: 13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice shall be included 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * in all copies or substantial portions of the Software. 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \file common_x86.c 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Check CPU capabilities & initialize optimized funtions for this particular 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * processor. 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Changed by Andre Werthmann for using the new SSE functions. 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \author Holger Waechtler <holger@akaflieg.extern.tu-berlin.de> 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * \author Andre Werthmann <wertmann@cs.uni-potsdam.de> 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* XXX these includes should probably go into imports.h or glheader.h */ 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if defined(USE_SSE_ASM) && defined(__linux__) 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <linux/version.h> 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if defined(USE_SSE_ASM) && defined(__FreeBSD__) 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <sys/types.h> 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <sys/sysctl.h> 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if defined(USE_SSE_ASM) && defined(__OpenBSD__) 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <sys/param.h> 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <sys/sysctl.h> 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <machine/cpu.h> 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "main/imports.h" 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "common_x86_asm.h" 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** Bitmask of X86_FEATURE_x bits */ 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint _mesa_x86_cpu_features = 0x0; 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic int detection_debug = GL_FALSE; 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* No reason for this to be public. 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgextern GLuint _ASMAPI _mesa_x86_has_cpuid(void); 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgextern void _ASMAPI _mesa_x86_cpuid(GLuint op, GLuint *reg_eax, GLuint *reg_ebx, GLuint *reg_ecx, GLuint *reg_edx); 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgextern GLuint _ASMAPI _mesa_x86_cpuid_eax(GLuint op); 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgextern GLuint _ASMAPI _mesa_x86_cpuid_ebx(GLuint op); 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgextern GLuint _ASMAPI _mesa_x86_cpuid_ecx(GLuint op); 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgextern GLuint _ASMAPI _mesa_x86_cpuid_edx(GLuint op); 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if defined(USE_SSE_ASM) 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * We must verify that the Streaming SIMD Extensions are truly supported 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * on this processor before we go ahead and hook out the optimized code. 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * However, I have been told by Alan Cox that all 2.4 (and later) Linux 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * kernels provide full SSE support on all processors that expose SSE via 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the CPUID mechanism. 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* These are assembly functions: */ 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgextern void _mesa_test_os_sse_support( void ); 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgextern void _mesa_test_os_sse_exception_support( void ); 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if defined(WIN32) 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifndef STATUS_FLOAT_MULTIPLE_TRAPS 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org# define STATUS_FLOAT_MULTIPLE_TRAPS (0xC00002B5L) 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic LONG WINAPI ExceptionFilter(LPEXCEPTION_POINTERS exp) 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org PEXCEPTION_RECORD rec = exp->ExceptionRecord; 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org PCONTEXT ctx = exp->ContextRecord; 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ( rec->ExceptionCode == EXCEPTION_ILLEGAL_INSTRUCTION ) { 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_debug(NULL, "EXCEPTION_ILLEGAL_INSTRUCTION\n" ); 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_x86_cpu_features &= ~(X86_FEATURE_XMM); 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if ( rec->ExceptionCode == STATUS_FLOAT_MULTIPLE_TRAPS ) { 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_debug(NULL, "STATUS_FLOAT_MULTIPLE_TRAPS\n"); 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Windows seems to clear the exception flag itself, we just have to increment Eip */ 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_debug(NULL, "UNEXPECTED EXCEPTION (0x%08x), terminating!\n" ); 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return EXCEPTION_EXECUTE_HANDLER; 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ( (ctx->ContextFlags & CONTEXT_CONTROL) != CONTEXT_CONTROL ) { 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_debug(NULL, "Context does not contain control registers, terminating!\n"); 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return EXCEPTION_EXECUTE_HANDLER; 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ctx->Eip += 3; 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return EXCEPTION_CONTINUE_EXECUTION; 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif /* WIN32 */ 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Check if SSE is supported. 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * If not, turn off the X86_FEATURE_XMM flag in _mesa_x86_cpu_features. 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid _mesa_check_os_sse_support( void ) 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if defined(__FreeBSD__) 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int ret, enabled; 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned int len; 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org len = sizeof(enabled); 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ret = sysctlbyname("hw.instruction_sse", &enabled, &len, NULL, 0); 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ret || !enabled) 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_x86_cpu_features &= ~(X86_FEATURE_XMM); 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#elif defined (__NetBSD__) 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int ret, enabled; 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org size_t len = sizeof(enabled); 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ret = sysctlbyname("machdep.sse", &enabled, &len, (void *)NULL, 0); 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ret || !enabled) 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_x86_cpu_features &= ~(X86_FEATURE_XMM); 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#elif defined(__OpenBSD__) 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int mib[2]; 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int ret, enabled; 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org size_t len = sizeof(enabled); 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mib[0] = CTL_MACHDEP; 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org mib[1] = CPU_SSE; 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ret = sysctl(mib, 2, &enabled, &len, NULL, 0); 149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (ret || !enabled) 150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_x86_cpu_features &= ~(X86_FEATURE_XMM); 151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#elif defined(WIN32) 153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LPTOP_LEVEL_EXCEPTION_FILTER oldFilter; 154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Install our ExceptionFilter */ 156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org oldFilter = SetUnhandledExceptionFilter( ExceptionFilter ); 157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ( cpu_has_xmm ) { 159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_debug(NULL, "Testing OS support for SSE...\n"); 160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_test_os_sse_support(); 162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ( cpu_has_xmm ) { 164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_debug(NULL, "Yes.\n"); 165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_debug(NULL, "No!\n"); 167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ( cpu_has_xmm ) { 171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_debug(NULL, "Testing OS support for SSE unmasked exceptions...\n"); 172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_test_os_sse_exception_support(); 174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ( cpu_has_xmm ) { 176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_debug(NULL, "Yes.\n"); 177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_debug(NULL, "No!\n"); 179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Restore previous exception filter */ 183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org SetUnhandledExceptionFilter( oldFilter ); 184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ( cpu_has_xmm ) { 186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_debug(NULL, "Tests of OS support for SSE passed.\n"); 187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_debug(NULL, "Tests of OS support for SSE failed!\n"); 189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#else 191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Do nothing on other platforms for now. 192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (detection_debug) 194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_debug(NULL, "Not testing OS support for SSE, leaving enabled.\n"); 195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif /* __FreeBSD__ */ 196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif /* USE_SSE_ASM */ 199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Initialize the _mesa_x86_cpu_features bitfield. 203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This is a no-op if called more than once. 204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org_mesa_get_x86_features(void) 207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org static int called = 0; 209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (called) 211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org called = 1; 214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef USE_X86_ASM 216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_x86_cpu_features = 0x0; 217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (_mesa_getenv( "MESA_NO_ASM")) { 219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!_mesa_x86_has_cpuid()) { 223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_debug(NULL, "CPUID not detected\n"); 224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint cpu_features; 227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint cpu_ext_features; 228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint cpu_ext_info; 229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org char cpu_vendor[13]; 230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint result; 231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* get vendor name */ 233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_x86_cpuid(0, &result, (GLuint *)(cpu_vendor + 0), (GLuint *)(cpu_vendor + 8), (GLuint *)(cpu_vendor + 4)); 234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cpu_vendor[12] = '\0'; 235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (detection_debug) 237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_debug(NULL, "CPU vendor: %s\n", cpu_vendor); 238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* get cpu features */ 240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cpu_features = _mesa_x86_cpuid_edx(1); 241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (cpu_features & X86_CPU_FPU) 243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_x86_cpu_features |= X86_FEATURE_FPU; 244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (cpu_features & X86_CPU_CMOV) 245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_x86_cpu_features |= X86_FEATURE_CMOV; 246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef USE_MMX_ASM 248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (cpu_features & X86_CPU_MMX) 249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_x86_cpu_features |= X86_FEATURE_MMX; 250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef USE_SSE_ASM 253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (cpu_features & X86_CPU_XMM) 254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_x86_cpu_features |= X86_FEATURE_XMM; 255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (cpu_features & X86_CPU_XMM2) 256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_x86_cpu_features |= X86_FEATURE_XMM2; 257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* query extended cpu features */ 260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((cpu_ext_info = _mesa_x86_cpuid_eax(0x80000000)) > 0x80000000) { 261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (cpu_ext_info >= 0x80000001) { 262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cpu_ext_features = _mesa_x86_cpuid_edx(0x80000001); 264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (cpu_features & X86_CPU_MMX) { 266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef USE_3DNOW_ASM 268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (cpu_ext_features & X86_CPUEXT_3DNOW) 269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_x86_cpu_features |= X86_FEATURE_3DNOW; 270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (cpu_ext_features & X86_CPUEXT_3DNOW_EXT) 271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_x86_cpu_features |= X86_FEATURE_3DNOWEXT; 272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef USE_MMX_ASM 275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (cpu_ext_features & X86_CPUEXT_MMX_EXT) 276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_x86_cpu_features |= X86_FEATURE_MMXEXT; 277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* query cpu name */ 282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (cpu_ext_info >= 0x80000002) { 283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org GLuint ofs; 284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org char cpu_name[49]; 285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (ofs = 0; ofs < 3; ofs++) 286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _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)); 287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org cpu_name[48] = '\0'; /* the name should be NULL terminated, but just to be sure */ 288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (detection_debug) 290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_debug(NULL, "CPU name: %s\n", cpu_name); 291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef USE_MMX_ASM 297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ( cpu_has_mmx ) { 298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ( _mesa_getenv( "MESA_NO_MMX" ) == 0 ) { 299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (detection_debug) 300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_debug(NULL, "MMX cpu detected.\n"); 301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_x86_cpu_features &= ~(X86_FEATURE_MMX); 303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef USE_3DNOW_ASM 308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ( cpu_has_3dnow ) { 309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ( _mesa_getenv( "MESA_NO_3DNOW" ) == 0 ) { 310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (detection_debug) 311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_debug(NULL, "3DNow! cpu detected.\n"); 312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_x86_cpu_features &= ~(X86_FEATURE_3DNOW); 314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#ifdef USE_SSE_ASM 319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ( cpu_has_xmm ) { 320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ( _mesa_getenv( "MESA_NO_SSE" ) == 0 ) { 321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (detection_debug) 322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_debug(NULL, "SSE cpu detected.\n"); 323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ( _mesa_getenv( "MESA_FORCE_SSE" ) == 0 ) { 324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_check_os_sse_support(); 325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_debug(NULL, "SSE cpu detected, but switched off by user.\n"); 328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org _mesa_x86_cpu_features &= ~(X86_FEATURE_XMM); 329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif /* USE_X86_ASM */ 334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (void) detection_debug; 336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 337