Merge remote branch 'origin/opengl-es-v2'
[mesa.git] / src / mesa / x86 / common_x86_asm.S
index 675711e44aab140ae21a8ae9271c900be7d1b343..ea4047a0e140c31f9ab937479623057459731bb7 100644 (file)
@@ -1,10 +1,8 @@
-/* $Id: common_x86_asm.S,v 1.2 2000/10/23 00:16:28 gareth Exp $ */
-
 /*
  * Mesa 3-D graphics library
- * Version:  3.5
+ * Version:  6.3
  *
- * Copyright (C) 1999-2000  Brian Paul   All Rights Reserved.
+ * 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"),
  * 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
 
-/* Intel vendor string
- */
-#define GENU   0x756e6547      /* "Genu" */
-#define INEI   0x49656e69      /* "ineI" */
-#define NTEL   0x6c65746e      /* "ntel" */
+ALIGNTEXT4
+GLOBL GLNAME(_mesa_x86_has_cpuid)
+HIDDEN(_mesa_x86_has_cpuid)
+GLNAME(_mesa_x86_has_cpuid):
 
-/* AMD vendor string
- */
-#define AUTH   0x68747541      /* "Auth" */
-#define ENTI   0x69746e65      /* "enti" */
-#define CAMD   0x444d4163      /* "cAMD" */
+       /* 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)
 
-       SEG_DATA
+       RET
 
-/* We might want to print out some useful messages.
- */
-LLBL( found_intel ):   STRING( "Genuine Intel processor found\n\0" )
-LLBL( found_amd ):     STRING( "Authentic AMD processor found\n\0" )
 
+ALIGNTEXT4
+GLOBL GLNAME(_mesa_x86_cpuid)
+HIDDEN(_mesa_x86_cpuid)
+GLNAME(_mesa_x86_cpuid):
 
-       SEG_TEXT
+       MOV_L   (REGOFF(4, ESP), EAX)           /* cpuid op */
+       PUSH_L  (EDI)
+       PUSH_L  (EBX)
 
-ALIGNTEXT4
-GLOBL GLNAME( gl_identify_x86_cpu_features )
-GLNAME( gl_identify_x86_cpu_features ):
+       CPUID
 
-       PUSH_L  ( EBX )
+       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
 
-       /* 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 )
+ALIGNTEXT4
+GLOBL GLNAME(_mesa_x86_cpuid_eax)
+HIDDEN(_mesa_x86_cpuid_eax)
+GLNAME(_mesa_x86_cpuid_eax):
 
-       /* Verify the ID Flag bit has been written.
-        */
-       CMP_L   ( ECX, EAX )
-       JZ      ( LLBL ( cpuid_done ) )
+       MOV_L   (REGOFF(4, ESP), EAX)           /* cpuid op */
+       PUSH_L  (EBX)
 
-       /* Get the CPU vendor info.
-        */
-       XOR_L   ( EAX, EAX )
        CPUID
 
-       /* Test for Intel processors.  We must look for the
-        * "GenuineIntel" string in EBX, ECX and EDX.
-        */
-       CMP_L   ( CONST(GENU), EBX )
-       JNE     ( LLBL( cpuid_amd ) )
-       CMP_L   ( CONST(INEI), EDX )
-       JNE     ( LLBL( cpuid_amd ) )
-       CMP_L   ( CONST(NTEL), ECX )
-       JNE     ( LLBL( cpuid_amd ) )
-
-       /* We have an Intel processor, so we can get the feature
-        * information with an CPUID input value of 1.
-        */
-       MOV_L   ( CONST(0x1), EAX )
+       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   ( EDX, EAX )
-       JMP     ( LLBL( cpuid_done ) )
+       MOV_L   (EBX, EAX)                      /* return EBX */
 
-LLBL( cpuid_amd ):
+       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)
 
-       /* Test for AMD processors.  We must look for the
-        * "AuthenticAMD" string in EBX, ECX and EDX.
-        */
-       CMP_L   ( CONST(AUTH), EBX )
-       JNE     ( LLBL( cpuid_other ) )
-       CMP_L   ( CONST(ENTI), EDX )
-       JNE     ( LLBL( cpuid_other ) )
-       CMP_L   ( CONST(CAMD), ECX )
-       JNE     ( LLBL( cpuid_other ) )
-
-       /* We have an AMD processor, so we can get the feature
-        * information after we verify that the extended functions are
-        * supported.
-        */
-       MOV_L   ( CONST(0x80000000), EAX )
        CPUID
-       TEST_L  ( EAX, EAX )
-       JZ      ( LLBL ( cpuid_failed ) )
+       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)
 
-       MOV_L   ( CONST(0x80000001), EAX )
        CPUID
-       MOV_L   ( EDX, EAX )
-       JMP     ( LLBL ( cpuid_done ) )
+       MOV_L   (EDX, EAX)                      /* return EDX */
 
-LLBL( cpuid_other ):
+       POP_L   (EBX)
+       RET
 
-       /* Test for other processors here when required.
-        */
+#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 )
 
-LLBL( cpuid_failed ):
+       RET
 
-       /* If we can't determine the feature information, we must
-        * return zero to indicate that no platform-specific
-        * optimizations can be used.
+
+/* 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.
         */
-       MOV_L   ( CONST(0), EAX )
+       STMXCSR ( REGOFF( -4, EBP ) )
 
-LLBL ( cpuid_done ):
+       /* Unmask the divide-by-zero exception and perform one.
+        */
+       STMXCSR ( REGOFF( -8, EBP ) )
+       AND_L   ( CONST( 0xfffffdff ), REGOFF( -8, EBP ) )
+       LDMXCSR ( REGOFF( -8, EBP ) )
 
-       POP_L   ( EBX )
+       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