1/* 2 * Mesa 3-D graphics library 3 * 4 * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included 14 * in all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 * OTHER DEALINGS IN THE SOFTWARE. 23 */ 24 25/* 26 * Check extended CPU capabilities. Now justs returns the raw CPUID 27 * feature information, allowing the higher level code to interpret the 28 * results. 29 * 30 * Written by Holger Waechtler <holger@akaflieg.extern.tu-berlin.de> 31 * 32 * Cleaned up and simplified by Gareth Hughes <gareth@valinux.com> 33 * 34 */ 35 36/* 37 * NOTE: Avoid using spaces in between '(' ')' and arguments, especially 38 * with macros like CONST, LLBL that expand to CONCAT(...). Putting spaces 39 * in there will break the build on some platforms. 40 */ 41 42#include "matypes.h" 43#include "assyntax.h" 44#include "common_x86_features.h" 45 46 SEG_TEXT 47 48ALIGNTEXT4 49GLOBL GLNAME(_mesa_x86_has_cpuid) 50HIDDEN(_mesa_x86_has_cpuid) 51GLNAME(_mesa_x86_has_cpuid): 52 53 /* Test for the CPUID command. If the ID Flag bit in EFLAGS 54 * (bit 21) is writable, the CPUID command is present */ 55 PUSHF_L 56 POP_L (EAX) 57 MOV_L (EAX, ECX) 58 XOR_L (CONST(0x00200000), EAX) 59 PUSH_L (EAX) 60 POPF_L 61 PUSHF_L 62 POP_L (EAX) 63 64 /* Verify the ID Flag bit has been written. */ 65 CMP_L (ECX, EAX) 66 SETNE (AL) 67 XOR_L (CONST(0xff), EAX) 68 69 RET 70 71 72ALIGNTEXT4 73GLOBL GLNAME(_mesa_x86_cpuid) 74HIDDEN(_mesa_x86_cpuid) 75GLNAME(_mesa_x86_cpuid): 76 77 MOV_L (REGOFF(4, ESP), EAX) /* cpuid op */ 78 PUSH_L (EDI) 79 PUSH_L (EBX) 80 81 CPUID 82 83 MOV_L (REGOFF(16, ESP), EDI) /* *eax */ 84 MOV_L (EAX, REGIND(EDI)) 85 MOV_L (REGOFF(20, ESP), EDI) /* *ebx */ 86 MOV_L (EBX, REGIND(EDI)) 87 MOV_L (REGOFF(24, ESP), EDI) /* *ecx */ 88 MOV_L (ECX, REGIND(EDI)) 89 MOV_L (REGOFF(28, ESP), EDI) /* *edx */ 90 MOV_L (EDX, REGIND(EDI)) 91 92 POP_L (EBX) 93 POP_L (EDI) 94 RET 95 96ALIGNTEXT4 97GLOBL GLNAME(_mesa_x86_cpuid_eax) 98HIDDEN(_mesa_x86_cpuid_eax) 99GLNAME(_mesa_x86_cpuid_eax): 100 101 MOV_L (REGOFF(4, ESP), EAX) /* cpuid op */ 102 PUSH_L (EBX) 103 104 CPUID 105 106 POP_L (EBX) 107 RET 108 109ALIGNTEXT4 110GLOBL GLNAME(_mesa_x86_cpuid_ebx) 111HIDDEN(_mesa_x86_cpuid_ebx) 112GLNAME(_mesa_x86_cpuid_ebx): 113 114 MOV_L (REGOFF(4, ESP), EAX) /* cpuid op */ 115 PUSH_L (EBX) 116 117 CPUID 118 MOV_L (EBX, EAX) /* return EBX */ 119 120 POP_L (EBX) 121 RET 122 123ALIGNTEXT4 124GLOBL GLNAME(_mesa_x86_cpuid_ecx) 125HIDDEN(_mesa_x86_cpuid_ecx) 126GLNAME(_mesa_x86_cpuid_ecx): 127 128 MOV_L (REGOFF(4, ESP), EAX) /* cpuid op */ 129 PUSH_L (EBX) 130 131 CPUID 132 MOV_L (ECX, EAX) /* return ECX */ 133 134 POP_L (EBX) 135 RET 136 137ALIGNTEXT4 138GLOBL GLNAME(_mesa_x86_cpuid_edx) 139HIDDEN(_mesa_x86_cpuid_edx) 140GLNAME(_mesa_x86_cpuid_edx): 141 142 MOV_L (REGOFF(4, ESP), EAX) /* cpuid op */ 143 PUSH_L (EBX) 144 145 CPUID 146 MOV_L (EDX, EAX) /* return EDX */ 147 148 POP_L (EBX) 149 RET 150 151#ifdef USE_SSE_ASM 152/* Execute an SSE instruction to see if the operating system correctly 153 * supports SSE. A signal handler for SIGILL should have been set 154 * before calling this function, otherwise this could kill the client 155 * application. 156 * 157 * -----> !!!! ATTENTION DEVELOPERS !!!! <----- 158 * 159 * If you're debugging with gdb and you get stopped in this function, 160 * just type 'continue'! Execution will proceed normally. 161 * See freedesktop.org bug #1709 for more info. 162 */ 163ALIGNTEXT4 164GLOBL GLNAME( _mesa_test_os_sse_support ) 165HIDDEN(_mesa_test_os_sse_support) 166GLNAME( _mesa_test_os_sse_support ): 167 168 XORPS ( XMM0, XMM0 ) 169 170 RET 171 172 173/* Perform an SSE divide-by-zero to see if the operating system 174 * correctly supports unmasked SIMD FPU exceptions. Signal handlers for 175 * SIGILL and SIGFPE should have been set before calling this function, 176 * otherwise this could kill the client application. 177 */ 178ALIGNTEXT4 179GLOBL GLNAME( _mesa_test_os_sse_exception_support ) 180HIDDEN(_mesa_test_os_sse_exception_support) 181GLNAME( _mesa_test_os_sse_exception_support ): 182 183 PUSH_L ( EBP ) 184 MOV_L ( ESP, EBP ) 185 SUB_L ( CONST( 8 ), ESP ) 186 187 /* Save the original MXCSR register value. 188 */ 189 STMXCSR ( REGOFF( -4, EBP ) ) 190 191 /* Unmask the divide-by-zero exception and perform one. 192 */ 193 STMXCSR ( REGOFF( -8, EBP ) ) 194 AND_L ( CONST( 0xfffffdff ), REGOFF( -8, EBP ) ) 195 LDMXCSR ( REGOFF( -8, EBP ) ) 196 197 XORPS ( XMM0, XMM0 ) 198 199 PUSH_L ( CONST( 0x3f800000 ) ) 200 PUSH_L ( CONST( 0x3f800000 ) ) 201 PUSH_L ( CONST( 0x3f800000 ) ) 202 PUSH_L ( CONST( 0x3f800000 ) ) 203 204 MOVUPS ( REGIND( ESP ), XMM1 ) 205 206 DIVPS ( XMM0, XMM1 ) 207 208 /* Restore the original MXCSR register value. 209 */ 210 LDMXCSR ( REGOFF( -4, EBP ) ) 211 212 LEAVE 213 RET 214 215#endif 216 217 218#if defined (__ELF__) && defined (__linux__) 219 .section .note.GNU-stack,"",%progbits 220#endif 221