commit 2b8d8989fb6f9c36baf166fc715182a1407ebadb
Author: Ian Romanick <[email protected]>
Date:   Sun Sep 28 20:31:46 2008 -0700

   Use 3Dnow! x86-64 routines only on processors that support 3Dnow!

   Added an x86-64 CPUID function and use it to detect 3Dnow!  If 3Dnow!
   is available, use _mesa_3dnow_transform_points4_3d_no_rot,
   _mesa_3dnow_transform_points4_perspective,
   _mesa_3dnow_transform_points4_2d_no_rot, and _mesa_3dnow_transform_points4_2d.

   This fixes long standing bug #8724.

diff --git src/mesa/x86-64/x86-64.c src/mesa/x86-64/x86-64.c
index 9ec43c8..96f8da8 100644
--- src/mesa/x86-64/x86-64.c
+++ src/mesa/x86-64/x86-64.c
@@ -41,7 +41,10 @@
#include "math/m_debug.h"
#endif

+extern void _mesa_x86_64_cpuid(unsigned int *regs);
+
DECLARE_XFORM_GROUP( x86_64, 4 )
+DECLARE_XFORM_GROUP( 3dnow, 4 )

#else
/* just to silence warning below */
@@ -81,6 +84,7 @@ static void message( const char *msg )
void _mesa_init_all_x86_64_transform_asm(void)
{
#ifdef USE_X86_64_ASM
+   unsigned int regs[4];

   if ( _mesa_getenv( "MESA_NO_ASM" ) ) {
     return;
@@ -88,24 +92,32 @@ void _mesa_init_all_x86_64_transform_asm(void)

   message("Initializing x86-64 optimizations\n");

-   ASSIGN_XFORM_GROUP( x86_64, 4 );

-   /*
   _mesa_transform_tab[4][MATRIX_GENERAL] =
      _mesa_x86_64_transform_points4_general;
   _mesa_transform_tab[4][MATRIX_IDENTITY] =
      _mesa_x86_64_transform_points4_identity;
   _mesa_transform_tab[4][MATRIX_3D] =
      _mesa_x86_64_transform_points4_3d;
-   _mesa_transform_tab[4][MATRIX_3D_NO_ROT] =
-      _mesa_x86_64_transform_points4_3d_no_rot;
-   _mesa_transform_tab[4][MATRIX_PERSPECTIVE] =
-      _mesa_x86_64_transform_points4_perspective;
-   _mesa_transform_tab[4][MATRIX_2D_NO_ROT] =
-      _mesa_x86_64_transform_points4_2d_no_rot;
-   _mesa_transform_tab[4][MATRIX_2D] =
-      _mesa_x86_64_transform_points4_2d;
-   */
+
+   regs[0] = 0x80000001;
+   regs[1] = 0x00000000;
+   regs[2] = 0x00000000;
+   regs[3] = 0x00000000;
+   _mesa_x86_64_cpuid(regs);
+   if (regs[3] & (1U << 31)) {
+      message("3Dnow! detected\n");
+      _mesa_transform_tab[4][MATRIX_3D_NO_ROT] =
+         _mesa_3dnow_transform_points4_3d_no_rot;
+      _mesa_transform_tab[4][MATRIX_PERSPECTIVE] =
+         _mesa_3dnow_transform_points4_perspective;
+      _mesa_transform_tab[4][MATRIX_2D_NO_ROT] =
+         _mesa_3dnow_transform_points4_2d_no_rot;
+      _mesa_transform_tab[4][MATRIX_2D] =
+         _mesa_3dnow_transform_points4_2d;
+
+   }
+

#ifdef DEBUG_MATH
   _math_test_all_transform_functions("x86_64");
diff --git src/mesa/x86-64/xform4.S src/mesa/x86-64/xform4.S
index 3f9c9d5..8059691 100644
--- src/mesa/x86-64/xform4.S
+++ src/mesa/x86-64/xform4.S
@@ -29,7 +29,22 @@
.text

.align 16
+.globl _mesa_x86_64_cpuid
+_mesa_x86_64_cpuid:
+       pushq   %rbx
+       movl    (%rdi), %eax
+       movl    8(%rdi), %ecx
+
+       cpuid
+
+       movl    %ebx, 4(%rdi)
+       movl    %eax, (%rdi)
+       movl    %ecx, 8(%rdi)
+       movl    %edx, 12(%rdi)
+       popq    %rbx
+       ret

+.align 16
.globl _mesa_x86_64_transform_points4_general
_mesa_x86_64_transform_points4_general:
/*
@@ -204,8 +219,8 @@ p4_identity_done:


.align 16
-.globl _mesa_x86_64_transform_points4_3d_no_rot
-_mesa_x86_64_transform_points4_3d_no_rot:
+.globl _mesa_3dnow_transform_points4_3d_no_rot
+_mesa_3dnow_transform_points4_3d_no_rot:

       movl V4F_COUNT(%rdx), %ecx      /* count */
       movzx V4F_STRIDE(%rdx), %eax    /* stride */
@@ -268,8 +283,8 @@ p4_3d_no_rot_done:


.align 16
-.globl _mesa_x86_64_transform_points4_perspective
-_mesa_x86_64_transform_points4_perspective:
+.globl _mesa_3dnow_transform_points4_perspective
+_mesa_3dnow_transform_points4_perspective:

       movl V4F_COUNT(%rdx), %ecx      /* count */
       movzx V4F_STRIDE(%rdx), %eax    /* stride */
@@ -334,8 +349,8 @@ p4_perspective_done:
       ret

.align 16
-.globl _mesa_x86_64_transform_points4_2d_no_rot
-_mesa_x86_64_transform_points4_2d_no_rot:
+.globl _mesa_3dnow_transform_points4_2d_no_rot
+_mesa_3dnow_transform_points4_2d_no_rot:

       movl V4F_COUNT(%rdx), %ecx      /* count */
       movzx V4F_STRIDE(%rdx), %eax    /* stride */
@@ -389,8 +404,8 @@ p4_2d_no_rot_done:


.align 16
-.globl _mesa_x86_64_transform_points4_2d
-_mesa_x86_64_transform_points4_2d:
+.globl _mesa_3dnow_transform_points4_2d
+_mesa_3dnow_transform_points4_2d:

       movl V4F_COUNT(%rdx), %ecx      /* count */
       movzx V4F_STRIDE(%rdx), %eax    /* stride */