Subversion Repositories shark

Rev

Rev 134 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
134 giacomo 1
/* $Id: asm_common_x86.s,v 1.1 2003-04-24 13:36:02 giacomo Exp $ */
2
 
3
/*
4
 * Mesa 3-D graphics library
5
 * Version:  4.0.3
6
 *
7
 * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.
8
 *
9
 * Permission is hereby granted, free of charge, to any person obtaining a
10
 * copy of this software and associated documentation files (the "Software"),
11
 * to deal in the Software without restriction, including without limitation
12
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13
 * and/or sell copies of the Software, and to permit persons to whom the
14
 * Software is furnished to do so, subject to the following conditions:
15
 *
16
 * The above copyright notice and this permission notice shall be included
17
 * in all copies or substantial portions of the Software.
18
 *
19
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
22
 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23
 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
 */
26
 
27
/*
28
 * Check extended CPU capabilities.  Now justs returns the raw CPUID
29
 * feature information, allowing the higher level code to interpret the
30
 * results.
31
 *
32
 * Written by Holger Waechtler <holger@akaflieg.extern.tu-berlin.de>
33
 *
34
 * Cleaned up and simplified by Gareth Hughes <gareth@valinux.com>
35
 */
36
 
37
/*
38
 * NOTE: Avoid using spaces in between '(' ')' and arguments, especially
39
 * with macros like CONST, LLBL that expand to CONCAT(...).  Putting spaces
40
 * in there will break the build on some platforms.
41
 */
42
 
43
#include "matypes.h"
44
#include "features_common_x86.h"
45
 
46
 
47
/* Intel vendor string
48
 */
49
#define GENU	0x756e6547	/* "Genu" */
50
#define INEI	0x49656e69	/* "ineI" */
51
#define NTEL	0x6c65746e	/* "ntel" */
52
 
53
/* AMD vendor string
54
 */
55
#define AUTH	0x68747541	/* "Auth" */
56
#define ENTI	0x69746e65	/* "enti" */
57
#define CAMD	0x444d4163	/* "cAMD" */
58
 
59
 
60
	SEG_DATA
61
 
62
/* We might want to print out some useful messages.
63
 */
64
GLNAME( found_intel ):	STRING( "Genuine Intel processor found\n\0" )
65
GLNAME( found_amd ):	STRING( "Authentic AMD processor found\n\0" )
66
 
67
 
68
	SEG_TEXT
69
 
70
ALIGNTEXT4
71
GLOBL GLNAME( _mesa_identify_x86_cpu_features )
72
GLNAME( _mesa_identify_x86_cpu_features ):
73
 
74
	PUSH_L	( EBX )
75
	PUSH_L	( ESI )
76
 
77
	/* Test for the CPUID command.  If the ID Flag bit in EFLAGS
78
	 * (bit 21) is writable, the CPUID command is present.
79
	 */
80
	PUSHF_L
81
	POP_L	( EAX )
82
	MOV_L	( EAX, ECX )
83
	XOR_L	( CONST(0x00200000), EAX )
84
	PUSH_L	( EAX )
85
	POPF_L
86
	PUSHF_L
87
	POP_L	( EAX )
88
 
89
	/* Verify the ID Flag bit has been written.
90
	 */
91
	CMP_L	( ECX, EAX )
92
	JZ	( LLBL (cpuid_done) )
93
 
94
	/* Get the CPU vendor info.
95
	 */
96
	XOR_L	( EAX, EAX )
97
	CPUID
98
 
99
	/* Test for Intel processors.  We must look for the
100
	 * "GenuineIntel" string in EBX, ECX and EDX.
101
	 */
102
	CMP_L	( CONST(GENU), EBX )
103
	JNE	( LLBL(cpuid_amd) )
104
	CMP_L	( CONST(INEI), EDX )
105
	JNE	( LLBL(cpuid_amd) )
106
	CMP_L	( CONST(NTEL), ECX )
107
	JNE	( LLBL(cpuid_amd) )
108
 
109
	/* We have an Intel processor, so we can get the feature
110
	 * information with an CPUID input value of 1.
111
	 */
112
	MOV_L	( CONST(0x1), EAX )
113
	CPUID
114
	MOV_L	( EDX, EAX )
115
 
116
	/* Mask out highest bit, which is used by AMD for 3dnow
117
         * Newer Intel have this bit set, but do not support 3dnow
118
 	 */
119
        AND_L   ( CONST(0X7FFFFFFF), EAX)
120
	JMP	( LLBL(cpuid_done) )
121
 
122
LLBL(cpuid_amd):
123
 
124
	/* Test for AMD processors.  We must look for the
125
	 * "AuthenticAMD" string in EBX, ECX and EDX.
126
	 */
127
	CMP_L	( CONST(AUTH), EBX )
128
	JNE	( LLBL(cpuid_other) )
129
	CMP_L	( CONST(ENTI), EDX )
130
	JNE	( LLBL(cpuid_other) )
131
	CMP_L	( CONST(CAMD), ECX )
132
	JNE	( LLBL(cpuid_other) )
133
 
134
	/* We have an AMD processor, so we can get the feature
135
	 * information after we verify that the extended functions are
136
	 * supported.
137
	 */
138
	/* The features we need are almost all in the extended set.  The
139
	 * exception is SSE enable, which is in the standard set (0x1).
140
	 */
141
	MOV_L	( CONST(0x1), EAX )
142
	CPUID
143
	TEST_L	( EAX, EAX )
144
	JZ	( LLBL (cpuid_failed) )
145
	MOV_L	( EDX, ESI )
146
 
147
	MOV_L	( CONST(0x80000000), EAX )
148
	CPUID
149
	TEST_L	( EAX, EAX )
150
	JZ	( LLBL (cpuid_failed) )
151
 
152
	MOV_L	( CONST(0x80000001), EAX )
153
	CPUID
154
	MOV_L	( EDX, EAX )
155
 
156
	AND_L	( CONST(0x02000000), ESI )	/* OR in the SSE bit */
157
	OR_L	( ESI, EAX )
158
 
159
	JMP	( LLBL (cpuid_done) )
160
 
161
LLBL(cpuid_other):
162
 
163
	/* Test for other processors here when required.
164
	 */
165
 
166
LLBL(cpuid_failed):
167
 
168
	/* If we can't determine the feature information, we must
169
	 * return zero to indicate that no platform-specific
170
	 * optimizations can be used.
171
	 */
172
	MOV_L	( CONST(0), EAX )
173
 
174
LLBL (cpuid_done):
175
 
176
	POP_L	( ESI )
177
	POP_L	( EBX )
178
	RET
179
 
180
 
181
#ifdef USE_SSE_ASM
182
/* Execute an SSE instruction to see if the operating system correctly
183
 * supports SSE.  A signal handler for SIGILL should have been set
184
 * before calling this function, otherwise this could kill the client
185
 * application.
186
 */
187
ALIGNTEXT4
188
GLOBL GLNAME( _mesa_test_os_sse_support )
189
GLNAME( _mesa_test_os_sse_support ):
190
 
191
	XORPS	( XMM0, XMM0 )
192
 
193
	RET
194
 
195
 
196
/* Perform an SSE divide-by-zero to see if the operating system
197
 * correctly supports unmasked SIMD FPU exceptions.  Signal handlers for
198
 * SIGILL and SIGFPE should have been set before calling this function,
199
 * otherwise this could kill the client application.
200
 */
201
ALIGNTEXT4
202
GLOBL GLNAME( _mesa_test_os_sse_exception_support )
203
GLNAME( _mesa_test_os_sse_exception_support ):
204
 
205
	PUSH_L	( EBP )
206
	MOV_L	( ESP, EBP )
207
	SUB_L	( CONST( 8 ), ESP )
208
 
209
	/* Save the original MXCSR register value.
210
	 */
211
	STMXCSR	( REGOFF( -4, EBP ) )
212
 
213
	/* Unmask the divide-by-zero exception and perform one.
214
	 */
215
	STMXCSR	( REGOFF( -8, EBP ) )
216
	AND_L	( CONST( 0xfffffdff ), REGOFF( -8, EBP ) )
217
	LDMXCSR	( REGOFF( -8, EBP ) )
218
 
219
	XORPS	( XMM0, XMM0 )
220
 
221
	PUSH_L	( CONST( 0x3f800000 ) )
222
	PUSH_L	( CONST( 0x3f800000 ) )
223
	PUSH_L	( CONST( 0x3f800000 ) )
224
	PUSH_L	( CONST( 0x3f800000 ) )
225
 
226
	MOVUPS	( REGIND( ESP ), XMM1 )
227
 
228
	ADD_L	( CONST( 32 ), ESP )
229
 
230
	DIVPS	( XMM0, XMM1 )
231
 
232
	/* Restore the original MXCSR register value.
233
	 */
234
	LDMXCSR	( REGOFF( -4, EBP ) )
235
 
236
	LEAVE
237
	RET
238
 
239
#endif