• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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