[MESA]
[reactos.git] / reactos / dll / opengl / mesa / x86 / common_x86_asm.S
diff --git a/reactos/dll/opengl/mesa/x86/common_x86_asm.S b/reactos/dll/opengl/mesa/x86/common_x86_asm.S
new file mode 100644 (file)
index 0000000..ea4047a
--- /dev/null
@@ -0,0 +1,220 @@
+/*
+ * Mesa 3-D graphics library
+ * Version:  6.3
+ *
+ * Copyright (C) 1999-2004  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Check extended CPU capabilities.  Now justs returns the raw CPUID
+ * feature information, allowing the higher level code to interpret the
+ * results.
+ *
+ * Written by Holger Waechtler <holger@akaflieg.extern.tu-berlin.de>
+ *
+ * Cleaned up and simplified by Gareth Hughes <gareth@valinux.com>
+ *
+ */
+
+/*
+ * NOTE: Avoid using spaces in between '(' ')' and arguments, especially
+ * with macros like CONST, LLBL that expand to CONCAT(...).  Putting spaces
+ * in there will break the build on some platforms.
+ */
+
+#include "matypes.h"
+#include "assyntax.h"
+#include "common_x86_features.h"
+
+       SEG_TEXT
+
+ALIGNTEXT4
+GLOBL GLNAME(_mesa_x86_has_cpuid)
+HIDDEN(_mesa_x86_has_cpuid)
+GLNAME(_mesa_x86_has_cpuid):
+
+       /* Test for the CPUID command.  If the ID Flag bit in EFLAGS
+        * (bit 21) is writable, the CPUID command is present */
+       PUSHF_L
+       POP_L   (EAX)
+       MOV_L   (EAX, ECX)
+       XOR_L   (CONST(0x00200000), EAX)
+       PUSH_L  (EAX)
+       POPF_L
+       PUSHF_L
+       POP_L   (EAX)
+
+       /* Verify the ID Flag bit has been written. */
+       CMP_L   (ECX, EAX)
+       SETNE   (AL)
+       XOR_L   (CONST(0xff), EAX)
+
+       RET
+
+
+ALIGNTEXT4
+GLOBL GLNAME(_mesa_x86_cpuid)
+HIDDEN(_mesa_x86_cpuid)
+GLNAME(_mesa_x86_cpuid):
+
+       MOV_L   (REGOFF(4, ESP), EAX)           /* cpuid op */
+       PUSH_L  (EDI)
+       PUSH_L  (EBX)
+
+       CPUID
+
+       MOV_L   (REGOFF(16, ESP), EDI)  /* *eax */
+       MOV_L   (EAX, REGIND(EDI))
+       MOV_L   (REGOFF(20, ESP), EDI)  /* *ebx */
+       MOV_L   (EBX, REGIND(EDI))
+       MOV_L   (REGOFF(24, ESP), EDI)  /* *ecx */
+       MOV_L   (ECX, REGIND(EDI))
+       MOV_L   (REGOFF(28, ESP), EDI)  /* *edx */
+       MOV_L   (EDX, REGIND(EDI))
+
+       POP_L   (EBX)
+       POP_L   (EDI)
+       RET
+
+ALIGNTEXT4
+GLOBL GLNAME(_mesa_x86_cpuid_eax)
+HIDDEN(_mesa_x86_cpuid_eax)
+GLNAME(_mesa_x86_cpuid_eax):
+
+       MOV_L   (REGOFF(4, ESP), EAX)           /* cpuid op */
+       PUSH_L  (EBX)
+
+       CPUID
+
+       POP_L   (EBX)
+       RET
+
+ALIGNTEXT4
+GLOBL GLNAME(_mesa_x86_cpuid_ebx)
+HIDDEN(_mesa_x86_cpuid_ebx)
+GLNAME(_mesa_x86_cpuid_ebx):
+
+       MOV_L   (REGOFF(4, ESP), EAX)           /* cpuid op */
+       PUSH_L  (EBX)
+
+       CPUID
+       MOV_L   (EBX, EAX)                      /* return EBX */
+
+       POP_L   (EBX)
+       RET
+
+ALIGNTEXT4
+GLOBL GLNAME(_mesa_x86_cpuid_ecx)
+HIDDEN(_mesa_x86_cpuid_ecx)
+GLNAME(_mesa_x86_cpuid_ecx):
+
+       MOV_L   (REGOFF(4, ESP), EAX)           /* cpuid op */
+       PUSH_L  (EBX)
+
+       CPUID
+       MOV_L   (ECX, EAX)                      /* return ECX */
+
+       POP_L   (EBX)
+       RET
+
+ALIGNTEXT4
+GLOBL GLNAME(_mesa_x86_cpuid_edx)
+HIDDEN(_mesa_x86_cpuid_edx)
+GLNAME(_mesa_x86_cpuid_edx):
+
+       MOV_L   (REGOFF(4, ESP), EAX)           /* cpuid op */
+       PUSH_L  (EBX)
+
+       CPUID
+       MOV_L   (EDX, EAX)                      /* return EDX */
+
+       POP_L   (EBX)
+       RET
+
+#ifdef USE_SSE_ASM
+/* Execute an SSE instruction to see if the operating system correctly
+ * supports SSE.  A signal handler for SIGILL should have been set
+ * before calling this function, otherwise this could kill the client
+ * application.
+ *
+ *        -----> !!!! ATTENTION DEVELOPERS !!!! <-----
+ *
+ * If you're debugging with gdb and you get stopped in this function,
+ * just type 'continue'!  Execution will proceed normally.
+ * See freedesktop.org bug #1709 for more info.
+ */
+ALIGNTEXT4
+GLOBL GLNAME( _mesa_test_os_sse_support )
+HIDDEN(_mesa_test_os_sse_support)
+GLNAME( _mesa_test_os_sse_support ):
+
+       XORPS   ( XMM0, XMM0 )
+
+       RET
+
+
+/* Perform an SSE divide-by-zero to see if the operating system
+ * correctly supports unmasked SIMD FPU exceptions.  Signal handlers for
+ * SIGILL and SIGFPE should have been set before calling this function,
+ * otherwise this could kill the client application.
+ */
+ALIGNTEXT4
+GLOBL GLNAME( _mesa_test_os_sse_exception_support )
+HIDDEN(_mesa_test_os_sse_exception_support)
+GLNAME( _mesa_test_os_sse_exception_support ):
+
+       PUSH_L  ( EBP )
+       MOV_L   ( ESP, EBP )
+       SUB_L   ( CONST( 8 ), ESP )
+
+       /* Save the original MXCSR register value.
+        */
+       STMXCSR ( REGOFF( -4, EBP ) )
+
+       /* Unmask the divide-by-zero exception and perform one.
+        */
+       STMXCSR ( REGOFF( -8, EBP ) )
+       AND_L   ( CONST( 0xfffffdff ), REGOFF( -8, EBP ) )
+       LDMXCSR ( REGOFF( -8, EBP ) )
+
+       XORPS   ( XMM0, XMM0 )
+
+       PUSH_L  ( CONST( 0x3f800000 ) )
+       PUSH_L  ( CONST( 0x3f800000 ) )
+       PUSH_L  ( CONST( 0x3f800000 ) )
+       PUSH_L  ( CONST( 0x3f800000 ) )
+
+       MOVUPS  ( REGIND( ESP ), XMM1 )
+
+       DIVPS   ( XMM0, XMM1 )
+
+       /* Restore the original MXCSR register value.
+        */
+       LDMXCSR ( REGOFF( -4, EBP ) )
+
+       LEAVE
+       RET
+
+#endif
+
+       
+#if defined (__ELF__) && defined (__linux__)
+       .section .note.GNU-stack,"",%progbits
+#endif