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 "assyntax.h" 43#include "common_x86_features.h" 44 45 SEG_TEXT 46 47ALIGNTEXT4 48GLOBL GLNAME(_mesa_x86_has_cpuid) 49HIDDEN(_mesa_x86_has_cpuid) 50GLNAME(_mesa_x86_has_cpuid): 51 _CET_ENDBR 52 /* Test for the CPUID command. If the ID Flag bit in EFLAGS 53 * (bit 21) is writable, the CPUID command is present */ 54 PUSHF_L 55 POP_L (EAX) 56 MOV_L (EAX, ECX) 57 XOR_L (CONST(0x00200000), EAX) 58 PUSH_L (EAX) 59 POPF_L 60 PUSHF_L 61 POP_L (EAX) 62 63 /* Verify the ID Flag bit has been written. */ 64 CMP_L (ECX, EAX) 65 SETNE (AL) 66 XOR_L (CONST(0xff), EAX) 67 68 RET 69 70 71ALIGNTEXT4 72GLOBL GLNAME(_mesa_x86_cpuid) 73HIDDEN(_mesa_x86_cpuid) 74GLNAME(_mesa_x86_cpuid): 75 _CET_ENDBR 76 MOV_L (REGOFF(4, ESP), EAX) /* cpuid op */ 77 PUSH_L (EDI) 78 PUSH_L (EBX) 79 80 CPUID 81 82 MOV_L (REGOFF(16, ESP), EDI) /* *eax */ 83 MOV_L (EAX, REGIND(EDI)) 84 MOV_L (REGOFF(20, ESP), EDI) /* *ebx */ 85 MOV_L (EBX, REGIND(EDI)) 86 MOV_L (REGOFF(24, ESP), EDI) /* *ecx */ 87 MOV_L (ECX, REGIND(EDI)) 88 MOV_L (REGOFF(28, ESP), EDI) /* *edx */ 89 MOV_L (EDX, REGIND(EDI)) 90 91 POP_L (EBX) 92 POP_L (EDI) 93 RET 94 95ALIGNTEXT4 96GLOBL GLNAME(_mesa_x86_cpuid_eax) 97HIDDEN(_mesa_x86_cpuid_eax) 98GLNAME(_mesa_x86_cpuid_eax): 99 _CET_ENDBR 100 MOV_L (REGOFF(4, ESP), EAX) /* cpuid op */ 101 PUSH_L (EBX) 102 103 CPUID 104 105 POP_L (EBX) 106 RET 107 108ALIGNTEXT4 109GLOBL GLNAME(_mesa_x86_cpuid_ebx) 110HIDDEN(_mesa_x86_cpuid_ebx) 111GLNAME(_mesa_x86_cpuid_ebx): 112 _CET_ENDBR 113 MOV_L (REGOFF(4, ESP), EAX) /* cpuid op */ 114 PUSH_L (EBX) 115 116 CPUID 117 MOV_L (EBX, EAX) /* return EBX */ 118 119 POP_L (EBX) 120 RET 121 122ALIGNTEXT4 123GLOBL GLNAME(_mesa_x86_cpuid_ecx) 124HIDDEN(_mesa_x86_cpuid_ecx) 125GLNAME(_mesa_x86_cpuid_ecx): 126 _CET_ENDBR 127 MOV_L (REGOFF(4, ESP), EAX) /* cpuid op */ 128 PUSH_L (EBX) 129 130 CPUID 131 MOV_L (ECX, EAX) /* return ECX */ 132 133 POP_L (EBX) 134 RET 135 136ALIGNTEXT4 137GLOBL GLNAME(_mesa_x86_cpuid_edx) 138HIDDEN(_mesa_x86_cpuid_edx) 139GLNAME(_mesa_x86_cpuid_edx): 140 _CET_ENDBR 141 MOV_L (REGOFF(4, ESP), EAX) /* cpuid op */ 142 PUSH_L (EBX) 143 144 CPUID 145 MOV_L (EDX, EAX) /* return EDX */ 146 147 POP_L (EBX) 148 RET 149 150#ifdef USE_SSE_ASM 151/* Execute an SSE instruction to see if the operating system correctly 152 * supports SSE. A signal handler for SIGILL should have been set 153 * before calling this function, otherwise this could kill the client 154 * application. 155 * 156 * -----> !!!! ATTENTION DEVELOPERS !!!! <----- 157 * 158 * If you're debugging with gdb and you get stopped in this function, 159 * just type 'continue'! Execution will proceed normally. 160 * See freedesktop.org bug #1709 for more info. 161 */ 162ALIGNTEXT4 163GLOBL GLNAME( _mesa_test_os_sse_support ) 164HIDDEN(_mesa_test_os_sse_support) 165GLNAME( _mesa_test_os_sse_support ): 166 _CET_ENDBR 167 XORPS ( XMM0, XMM0 ) 168 169 RET 170 171 172/* Perform an SSE divide-by-zero to see if the operating system 173 * correctly supports unmasked SIMD FPU exceptions. Signal handlers for 174 * SIGILL and SIGFPE should have been set before calling this function, 175 * otherwise this could kill the client application. 176 */ 177ALIGNTEXT4 178GLOBL GLNAME( _mesa_test_os_sse_exception_support ) 179HIDDEN(_mesa_test_os_sse_exception_support) 180GLNAME( _mesa_test_os_sse_exception_support ): 181 _CET_ENDBR 182 PUSH_L ( EBP ) 183 MOV_L ( ESP, EBP ) 184 SUB_L ( CONST( 8 ), ESP ) 185 186 /* Save the original MXCSR register value. 187 */ 188 STMXCSR ( REGOFF( -4, EBP ) ) 189 190 /* Unmask the divide-by-zero exception and perform one. 191 */ 192 STMXCSR ( REGOFF( -8, EBP ) ) 193 AND_L ( CONST( 0xfffffdff ), REGOFF( -8, EBP ) ) 194 LDMXCSR ( REGOFF( -8, EBP ) ) 195 196 XORPS ( XMM0, XMM0 ) 197 198 PUSH_L ( CONST( 0x3f800000 ) ) 199 PUSH_L ( CONST( 0x3f800000 ) ) 200 PUSH_L ( CONST( 0x3f800000 ) ) 201 PUSH_L ( CONST( 0x3f800000 ) ) 202 203 MOVUPS ( REGIND( ESP ), XMM1 ) 204 205 DIVPS ( XMM0, XMM1 ) 206 207 /* Restore the original MXCSR register value. 208 */ 209 LDMXCSR ( REGOFF( -4, EBP ) ) 210 211 LEAVE 212 RET 213 214#endif 215 216 217#if defined (__ELF__) && defined (__linux__) 218 .section .note.GNU-stack,"",%progbits 219#endif 220