Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / mesa / x86 / common_x86_asm.S
1 /*
2  * Mesa 3-D graphics library
3  * Version:  6.3
4  *
5  * Copyright (C) 1999-2004  Brian Paul   All Rights Reserved.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a
8  * copy of this software and associated documentation files (the "Software"),
9  * to deal in the Software without restriction, including without limitation
10  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11  * and/or sell copies of the Software, and to permit persons to whom the
12  * Software is furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included
15  * in all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR 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 "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