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 a/src/mesa/x86-64/x86-64.c b/src/mesa/x86-64/x86-64.c
index 9ec43c8..96f8da8 100644
--- a/src/mesa/x86-64/x86-64.c
+++ b/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 @@
 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 @@
 
    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 a/src/mesa/x86-64/xform4.S b/src/mesa/x86-64/xform4.S
index 3f9c9d5..8059691 100644
--- a/src/mesa/x86-64/xform4.S
+++ b/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 @@
 
 	
 .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 @@
 
 	
 .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 @@
 	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 @@
 
 	
 .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 */