Details | 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 |