/* * Mesa 3-D graphics library * * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. */ /* * Check extended CPU capabilities. Now justs returns the raw CPUID * feature information, allowing the higher level code to interpret the * results. * * Written by Holger Waechtler <holger@akaflieg.extern.tu-berlin.de> * * Cleaned up and simplified by Gareth Hughes <gareth@valinux.com> * */ /* * NOTE: Avoid using spaces in between '(' ')' and arguments, especially * with macros like CONST, LLBL that expand to CONCAT(...). Putting spaces * in there will break the build on some platforms. */ #include "matypes.h" #include "assyntax.h" #include "common_x86_features.h" SEG_TEXT ALIGNTEXT4 GLOBL GLNAME(_mesa_x86_has_cpuid) HIDDEN(_mesa_x86_has_cpuid) GLNAME(_mesa_x86_has_cpuid): /* Test for the CPUID command. If the ID Flag bit in EFLAGS * (bit 21) is writable, the CPUID command is present */ PUSHF_L POP_L (EAX) MOV_L (EAX, ECX) XOR_L (CONST(0x00200000), EAX) PUSH_L (EAX) POPF_L PUSHF_L POP_L (EAX) /* Verify the ID Flag bit has been written. */ CMP_L (ECX, EAX) SETNE (AL) XOR_L (CONST(0xff), EAX) RET ALIGNTEXT4 GLOBL GLNAME(_mesa_x86_cpuid) HIDDEN(_mesa_x86_cpuid) GLNAME(_mesa_x86_cpuid): MOV_L (REGOFF(4, ESP), EAX) /* cpuid op */ PUSH_L (EDI) PUSH_L (EBX) CPUID MOV_L (REGOFF(16, ESP), EDI) /* *eax */ MOV_L (EAX, REGIND(EDI)) MOV_L (REGOFF(20, ESP), EDI) /* *ebx */ MOV_L (EBX, REGIND(EDI)) MOV_L (REGOFF(24, ESP), EDI) /* *ecx */ MOV_L (ECX, REGIND(EDI)) MOV_L (REGOFF(28, ESP), EDI) /* *edx */ MOV_L (EDX, REGIND(EDI)) POP_L (EBX) POP_L (EDI) RET ALIGNTEXT4 GLOBL GLNAME(_mesa_x86_cpuid_eax) HIDDEN(_mesa_x86_cpuid_eax) GLNAME(_mesa_x86_cpuid_eax): MOV_L (REGOFF(4, ESP), EAX) /* cpuid op */ PUSH_L (EBX) CPUID POP_L (EBX) RET ALIGNTEXT4 GLOBL GLNAME(_mesa_x86_cpuid_ebx) HIDDEN(_mesa_x86_cpuid_ebx) GLNAME(_mesa_x86_cpuid_ebx): MOV_L (REGOFF(4, ESP), EAX) /* cpuid op */ PUSH_L (EBX) CPUID MOV_L (EBX, EAX) /* return EBX */ POP_L (EBX) RET ALIGNTEXT4 GLOBL GLNAME(_mesa_x86_cpuid_ecx) HIDDEN(_mesa_x86_cpuid_ecx) GLNAME(_mesa_x86_cpuid_ecx): MOV_L (REGOFF(4, ESP), EAX) /* cpuid op */ PUSH_L (EBX) CPUID MOV_L (ECX, EAX) /* return ECX */ POP_L (EBX) RET ALIGNTEXT4 GLOBL GLNAME(_mesa_x86_cpuid_edx) HIDDEN(_mesa_x86_cpuid_edx) GLNAME(_mesa_x86_cpuid_edx): MOV_L (REGOFF(4, ESP), EAX) /* cpuid op */ PUSH_L (EBX) CPUID MOV_L (EDX, EAX) /* return EDX */ POP_L (EBX) RET #ifdef USE_SSE_ASM /* Execute an SSE instruction to see if the operating system correctly * supports SSE. A signal handler for SIGILL should have been set * before calling this function, otherwise this could kill the client * application. * * -----> !!!! ATTENTION DEVELOPERS !!!! <----- * * If you're debugging with gdb and you get stopped in this function, * just type 'continue'! Execution will proceed normally. * See freedesktop.org bug #1709 for more info. */ ALIGNTEXT4 GLOBL GLNAME( _mesa_test_os_sse_support ) HIDDEN(_mesa_test_os_sse_support) GLNAME( _mesa_test_os_sse_support ): XORPS ( XMM0, XMM0 ) RET /* Perform an SSE divide-by-zero to see if the operating system * correctly supports unmasked SIMD FPU exceptions. Signal handlers for * SIGILL and SIGFPE should have been set before calling this function, * otherwise this could kill the client application. */ ALIGNTEXT4 GLOBL GLNAME( _mesa_test_os_sse_exception_support ) HIDDEN(_mesa_test_os_sse_exception_support) GLNAME( _mesa_test_os_sse_exception_support ): PUSH_L ( EBP ) MOV_L ( ESP, EBP ) SUB_L ( CONST( 8 ), ESP ) /* Save the original MXCSR register value. */ STMXCSR ( REGOFF( -4, EBP ) ) /* Unmask the divide-by-zero exception and perform one. */ STMXCSR ( REGOFF( -8, EBP ) ) AND_L ( CONST( 0xfffffdff ), REGOFF( -8, EBP ) ) LDMXCSR ( REGOFF( -8, EBP ) ) XORPS ( XMM0, XMM0 ) PUSH_L ( CONST( 0x3f800000 ) ) PUSH_L ( CONST( 0x3f800000 ) ) PUSH_L ( CONST( 0x3f800000 ) ) PUSH_L ( CONST( 0x3f800000 ) ) MOVUPS ( REGIND( ESP ), XMM1 ) DIVPS ( XMM0, XMM1 ) /* Restore the original MXCSR register value. */ LDMXCSR ( REGOFF( -4, EBP ) ) LEAVE RET #endif #if defined (__ELF__) && defined (__linux__) .section .note.GNU-stack,"",%progbits #endif