Home | History | Annotate | Download | only in x86
      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 (at) akaflieg.extern.tu-berlin.de>
     31  *
     32  * Cleaned up and simplified by Gareth Hughes <gareth (at) 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 
     48 ALIGNTEXT4
     49 GLOBL GLNAME(_mesa_x86_has_cpuid)
     50 HIDDEN(_mesa_x86_has_cpuid)
     51 GLNAME(_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 
     72 ALIGNTEXT4
     73 GLOBL GLNAME(_mesa_x86_cpuid)
     74 HIDDEN(_mesa_x86_cpuid)
     75 GLNAME(_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 
     96 ALIGNTEXT4
     97 GLOBL GLNAME(_mesa_x86_cpuid_eax)
     98 HIDDEN(_mesa_x86_cpuid_eax)
     99 GLNAME(_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 
    109 ALIGNTEXT4
    110 GLOBL GLNAME(_mesa_x86_cpuid_ebx)
    111 HIDDEN(_mesa_x86_cpuid_ebx)
    112 GLNAME(_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 
    123 ALIGNTEXT4
    124 GLOBL GLNAME(_mesa_x86_cpuid_ecx)
    125 HIDDEN(_mesa_x86_cpuid_ecx)
    126 GLNAME(_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 
    137 ALIGNTEXT4
    138 GLOBL GLNAME(_mesa_x86_cpuid_edx)
    139 HIDDEN(_mesa_x86_cpuid_edx)
    140 GLNAME(_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  */
    163 ALIGNTEXT4
    164 GLOBL GLNAME( _mesa_test_os_sse_support )
    165 HIDDEN(_mesa_test_os_sse_support)
    166 GLNAME( _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  */
    178 ALIGNTEXT4
    179 GLOBL GLNAME( _mesa_test_os_sse_exception_support )
    180 HIDDEN(_mesa_test_os_sse_exception_support)
    181 GLNAME( _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