1848b8605Smrg/* 2848b8605Smrg * Mesa 3-D graphics library 3848b8605Smrg * 4848b8605Smrg * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. 5848b8605Smrg * 6848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a 7848b8605Smrg * copy of this software and associated documentation files (the "Software"), 8848b8605Smrg * to deal in the Software without restriction, including without limitation 9848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the 11848b8605Smrg * Software is furnished to do so, subject to the following conditions: 12848b8605Smrg * 13848b8605Smrg * The above copyright notice and this permission notice shall be included 14848b8605Smrg * in all copies or substantial portions of the Software. 15848b8605Smrg * 16848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17848b8605Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20848b8605Smrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21848b8605Smrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22848b8605Smrg * OTHER DEALINGS IN THE SOFTWARE. 23848b8605Smrg */ 24848b8605Smrg 25848b8605Smrg/* 26848b8605Smrg * Check extended CPU capabilities. Now justs returns the raw CPUID 27848b8605Smrg * feature information, allowing the higher level code to interpret the 28848b8605Smrg * results. 29848b8605Smrg * 30848b8605Smrg * Written by Holger Waechtler <holger@akaflieg.extern.tu-berlin.de> 31848b8605Smrg * 32848b8605Smrg * Cleaned up and simplified by Gareth Hughes <gareth@valinux.com> 33848b8605Smrg * 34848b8605Smrg */ 35848b8605Smrg 36848b8605Smrg/* 37848b8605Smrg * NOTE: Avoid using spaces in between '(' ')' and arguments, especially 38848b8605Smrg * with macros like CONST, LLBL that expand to CONCAT(...). Putting spaces 39848b8605Smrg * in there will break the build on some platforms. 40848b8605Smrg */ 41848b8605Smrg 42848b8605Smrg#include "matypes.h" 43848b8605Smrg#include "assyntax.h" 44848b8605Smrg#include "common_x86_features.h" 45848b8605Smrg 46848b8605Smrg SEG_TEXT 47848b8605Smrg 48848b8605SmrgALIGNTEXT4 49848b8605SmrgGLOBL GLNAME(_mesa_x86_has_cpuid) 50848b8605SmrgHIDDEN(_mesa_x86_has_cpuid) 51848b8605SmrgGLNAME(_mesa_x86_has_cpuid): 52848b8605Smrg 53848b8605Smrg /* Test for the CPUID command. If the ID Flag bit in EFLAGS 54848b8605Smrg * (bit 21) is writable, the CPUID command is present */ 55848b8605Smrg PUSHF_L 56848b8605Smrg POP_L (EAX) 57848b8605Smrg MOV_L (EAX, ECX) 58848b8605Smrg XOR_L (CONST(0x00200000), EAX) 59848b8605Smrg PUSH_L (EAX) 60848b8605Smrg POPF_L 61848b8605Smrg PUSHF_L 62848b8605Smrg POP_L (EAX) 63848b8605Smrg 64848b8605Smrg /* Verify the ID Flag bit has been written. */ 65848b8605Smrg CMP_L (ECX, EAX) 66848b8605Smrg SETNE (AL) 67848b8605Smrg XOR_L (CONST(0xff), EAX) 68848b8605Smrg 69848b8605Smrg RET 70848b8605Smrg 71848b8605Smrg 72848b8605SmrgALIGNTEXT4 73848b8605SmrgGLOBL GLNAME(_mesa_x86_cpuid) 74848b8605SmrgHIDDEN(_mesa_x86_cpuid) 75848b8605SmrgGLNAME(_mesa_x86_cpuid): 76848b8605Smrg 77848b8605Smrg MOV_L (REGOFF(4, ESP), EAX) /* cpuid op */ 78848b8605Smrg PUSH_L (EDI) 79848b8605Smrg PUSH_L (EBX) 80848b8605Smrg 81848b8605Smrg CPUID 82848b8605Smrg 83848b8605Smrg MOV_L (REGOFF(16, ESP), EDI) /* *eax */ 84848b8605Smrg MOV_L (EAX, REGIND(EDI)) 85848b8605Smrg MOV_L (REGOFF(20, ESP), EDI) /* *ebx */ 86848b8605Smrg MOV_L (EBX, REGIND(EDI)) 87848b8605Smrg MOV_L (REGOFF(24, ESP), EDI) /* *ecx */ 88848b8605Smrg MOV_L (ECX, REGIND(EDI)) 89848b8605Smrg MOV_L (REGOFF(28, ESP), EDI) /* *edx */ 90848b8605Smrg MOV_L (EDX, REGIND(EDI)) 91848b8605Smrg 92848b8605Smrg POP_L (EBX) 93848b8605Smrg POP_L (EDI) 94848b8605Smrg RET 95848b8605Smrg 96848b8605SmrgALIGNTEXT4 97848b8605SmrgGLOBL GLNAME(_mesa_x86_cpuid_eax) 98848b8605SmrgHIDDEN(_mesa_x86_cpuid_eax) 99848b8605SmrgGLNAME(_mesa_x86_cpuid_eax): 100848b8605Smrg 101848b8605Smrg MOV_L (REGOFF(4, ESP), EAX) /* cpuid op */ 102848b8605Smrg PUSH_L (EBX) 103848b8605Smrg 104848b8605Smrg CPUID 105848b8605Smrg 106848b8605Smrg POP_L (EBX) 107848b8605Smrg RET 108848b8605Smrg 109848b8605SmrgALIGNTEXT4 110848b8605SmrgGLOBL GLNAME(_mesa_x86_cpuid_ebx) 111848b8605SmrgHIDDEN(_mesa_x86_cpuid_ebx) 112848b8605SmrgGLNAME(_mesa_x86_cpuid_ebx): 113848b8605Smrg 114848b8605Smrg MOV_L (REGOFF(4, ESP), EAX) /* cpuid op */ 115848b8605Smrg PUSH_L (EBX) 116848b8605Smrg 117848b8605Smrg CPUID 118848b8605Smrg MOV_L (EBX, EAX) /* return EBX */ 119848b8605Smrg 120848b8605Smrg POP_L (EBX) 121848b8605Smrg RET 122848b8605Smrg 123848b8605SmrgALIGNTEXT4 124848b8605SmrgGLOBL GLNAME(_mesa_x86_cpuid_ecx) 125848b8605SmrgHIDDEN(_mesa_x86_cpuid_ecx) 126848b8605SmrgGLNAME(_mesa_x86_cpuid_ecx): 127848b8605Smrg 128848b8605Smrg MOV_L (REGOFF(4, ESP), EAX) /* cpuid op */ 129848b8605Smrg PUSH_L (EBX) 130848b8605Smrg 131848b8605Smrg CPUID 132848b8605Smrg MOV_L (ECX, EAX) /* return ECX */ 133848b8605Smrg 134848b8605Smrg POP_L (EBX) 135848b8605Smrg RET 136848b8605Smrg 137848b8605SmrgALIGNTEXT4 138848b8605SmrgGLOBL GLNAME(_mesa_x86_cpuid_edx) 139848b8605SmrgHIDDEN(_mesa_x86_cpuid_edx) 140848b8605SmrgGLNAME(_mesa_x86_cpuid_edx): 141848b8605Smrg 142848b8605Smrg MOV_L (REGOFF(4, ESP), EAX) /* cpuid op */ 143848b8605Smrg PUSH_L (EBX) 144848b8605Smrg 145848b8605Smrg CPUID 146848b8605Smrg MOV_L (EDX, EAX) /* return EDX */ 147848b8605Smrg 148848b8605Smrg POP_L (EBX) 149848b8605Smrg RET 150848b8605Smrg 151848b8605Smrg#ifdef USE_SSE_ASM 152848b8605Smrg/* Execute an SSE instruction to see if the operating system correctly 153848b8605Smrg * supports SSE. A signal handler for SIGILL should have been set 154848b8605Smrg * before calling this function, otherwise this could kill the client 155848b8605Smrg * application. 156848b8605Smrg * 157848b8605Smrg * -----> !!!! ATTENTION DEVELOPERS !!!! <----- 158848b8605Smrg * 159848b8605Smrg * If you're debugging with gdb and you get stopped in this function, 160848b8605Smrg * just type 'continue'! Execution will proceed normally. 161848b8605Smrg * See freedesktop.org bug #1709 for more info. 162848b8605Smrg */ 163848b8605SmrgALIGNTEXT4 164848b8605SmrgGLOBL GLNAME( _mesa_test_os_sse_support ) 165848b8605SmrgHIDDEN(_mesa_test_os_sse_support) 166848b8605SmrgGLNAME( _mesa_test_os_sse_support ): 167848b8605Smrg 168848b8605Smrg XORPS ( XMM0, XMM0 ) 169848b8605Smrg 170848b8605Smrg RET 171848b8605Smrg 172848b8605Smrg 173848b8605Smrg/* Perform an SSE divide-by-zero to see if the operating system 174848b8605Smrg * correctly supports unmasked SIMD FPU exceptions. Signal handlers for 175848b8605Smrg * SIGILL and SIGFPE should have been set before calling this function, 176848b8605Smrg * otherwise this could kill the client application. 177848b8605Smrg */ 178848b8605SmrgALIGNTEXT4 179848b8605SmrgGLOBL GLNAME( _mesa_test_os_sse_exception_support ) 180848b8605SmrgHIDDEN(_mesa_test_os_sse_exception_support) 181848b8605SmrgGLNAME( _mesa_test_os_sse_exception_support ): 182848b8605Smrg 183848b8605Smrg PUSH_L ( EBP ) 184848b8605Smrg MOV_L ( ESP, EBP ) 185848b8605Smrg SUB_L ( CONST( 8 ), ESP ) 186848b8605Smrg 187848b8605Smrg /* Save the original MXCSR register value. 188848b8605Smrg */ 189848b8605Smrg STMXCSR ( REGOFF( -4, EBP ) ) 190848b8605Smrg 191848b8605Smrg /* Unmask the divide-by-zero exception and perform one. 192848b8605Smrg */ 193848b8605Smrg STMXCSR ( REGOFF( -8, EBP ) ) 194848b8605Smrg AND_L ( CONST( 0xfffffdff ), REGOFF( -8, EBP ) ) 195848b8605Smrg LDMXCSR ( REGOFF( -8, EBP ) ) 196848b8605Smrg 197848b8605Smrg XORPS ( XMM0, XMM0 ) 198848b8605Smrg 199848b8605Smrg PUSH_L ( CONST( 0x3f800000 ) ) 200848b8605Smrg PUSH_L ( CONST( 0x3f800000 ) ) 201848b8605Smrg PUSH_L ( CONST( 0x3f800000 ) ) 202848b8605Smrg PUSH_L ( CONST( 0x3f800000 ) ) 203848b8605Smrg 204848b8605Smrg MOVUPS ( REGIND( ESP ), XMM1 ) 205848b8605Smrg 206848b8605Smrg DIVPS ( XMM0, XMM1 ) 207848b8605Smrg 208848b8605Smrg /* Restore the original MXCSR register value. 209848b8605Smrg */ 210848b8605Smrg LDMXCSR ( REGOFF( -4, EBP ) ) 211848b8605Smrg 212848b8605Smrg LEAVE 213848b8605Smrg RET 214848b8605Smrg 215848b8605Smrg#endif 216848b8605Smrg 217848b8605Smrg 218848b8605Smrg#if defined (__ELF__) && defined (__linux__) 219848b8605Smrg .section .note.GNU-stack,"",%progbits 220848b8605Smrg#endif 221