changeset 2272:c26a9eff0993

cpu detection fixed
author arpi
date Fri, 19 Oct 2001 02:00:45 +0000
parents a8d57bbc4413
children e407fc4562f1
files Makefile cpudetect.c mplayer.c
diffstat 3 files changed, 70 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile	Fri Oct 19 01:53:45 2001 +0000
+++ b/Makefile	Fri Oct 19 02:00:45 2001 +0000
@@ -16,7 +16,7 @@
 #prefix = /usr/local
 BINDIR = ${prefix}/bin
 # BINDIR = /usr/local/bin
-SRCS = postproc/swscale.c postproc/postprocess.c mp_msg.c open.c parse_es.c ac3-iec958.c find_sub.c aviprint.c dec_audio.c dec_video.c aviwrite.c aviheader.c asfheader.c demux_avi.c demux_asf.c demux_mpg.c demux_mov.c demuxer.c stream.c codec-cfg.c subreader.c linux/getch2.c linux/timer-lx.c linux/shmem.c xa/xa_gsm.c xa/rle8.c lirc_mp.c cfgparser.c mixer.c dvdauth.c spudec.c $(STREAM_SRCS)
+SRCS = cpudetect.c postproc/swscale.c postproc/postprocess.c mp_msg.c open.c parse_es.c ac3-iec958.c find_sub.c aviprint.c dec_audio.c dec_video.c aviwrite.c aviheader.c asfheader.c demux_avi.c demux_asf.c demux_mpg.c demux_mov.c demuxer.c stream.c codec-cfg.c subreader.c linux/getch2.c linux/timer-lx.c linux/shmem.c xa/xa_gsm.c xa/rle8.c lirc_mp.c cfgparser.c mixer.c dvdauth.c spudec.c $(STREAM_SRCS)
 OBJS = $(SRCS:.c=.o)
 CFLAGS = $(OPTFLAGS) -Iloader -Ilibvo $(CSS_INC) $(EXTRA_INC) # -Wall
 A_LIBS = -Lmp3lib -lMP3 -Llibac3 -lac3 $(ALSA_LIB) $(ESD_LIB)
--- a/cpudetect.c	Fri Oct 19 01:53:45 2001 +0000
+++ b/cpudetect.c	Fri Oct 19 02:00:45 2001 +0000
@@ -14,7 +14,7 @@
 #include <signal.h>
 #endif
 
-#define X86_FXSR_MAGIC
+//#define X86_FXSR_MAGIC
 /* Thanks to the FreeBSD project for some of this cpuid code, and 
  * help understanding how to use it.  Thanks to the Mesa 
  * team for SSE support detection and more cpu detect code.
@@ -25,40 +25,58 @@
 CpuCaps gCpuCaps;
 static void check_os_katmai_support( void );
 
-#if 0
+#if 1
+// return TRUE if cpuid supported
 static int has_cpuid()
 {
 	int a, c;
-	__asm __volatile(
-	"pushl %%ebx;"
-	/* Test for the CPUID command.  If the ID Flag bit in EFLAGS
-	 * (bit 21) is writable, the CPUID command is present */
-	"pushfl;"
-	"popl %%eax;"
-	"movl %%ecx, %%eax;"
-	"xorl %%eax, 0x00200000;"
-	"push %%eax;"
-	"popfl;"
-	"pushfl;"
-	"popl %%eax;"
-	"popl %%ebx"
-	: "=a" (a), "=c" (c)
-	:
-	: "cx"
-	 );
-	/* FIXME: I have no clue on intel assembly. */
-	return (a==c);
+
+// code from libavcodec:
+    __asm__ __volatile__ (
+                          /* See if CPUID instruction is supported ... */
+                          /* ... Get copies of EFLAGS into eax and ecx */
+                          "pushf\n\t"
+                          "popl %0\n\t"
+                          "movl %0, %1\n\t"
+                          
+                          /* ... Toggle the ID bit in one copy and store */
+                          /*     to the EFLAGS reg */
+                          "xorl $0x200000, %0\n\t"
+                          "push %0\n\t"
+                          "popf\n\t"
+                          
+                          /* ... Get the (hopefully modified) EFLAGS */
+                          "pushf\n\t"
+                          "popl %0\n\t"
+                          : "=a" (a), "=c" (c)
+                          :
+                          : "cc" 
+                          );
+
+	return (a!=c);
 }
 #endif
 
 static void
 do_cpuid(unsigned int ax, unsigned int *p)
 {
+#if 0
 	__asm __volatile(
 	"cpuid;"
 	: "=a" (p[0]), "=b" (p[1]), "=c" (p[2]), "=d" (p[3])
 	:  "0" (ax)
 	);
+#else
+// code from libavcodec:
+    __asm __volatile
+	("movl %%ebx, %%esi\n\t"
+         "cpuid\n\t"
+         "xchgl %%ebx, %%esi"
+         : "=a" (p[0]), "=S" (p[1]),
+           "=c" (p[2]), "=d" (p[3])
+         : "0" (ax));
+#endif
+
 }
 
 
@@ -68,11 +86,14 @@
 	unsigned int regs2[4];
 	
 	bzero(caps, sizeof(*caps));
+	printf("CPUid available: %s\n",has_cpuid()?"yes":"no");
 	/*if (!has_cpuid())
 		return;*/
 	do_cpuid(0x00000000, regs);
+	printf("CPU vendor name: %.4s%.4s%.4s\n",&regs[1],&regs[3],&regs[2]);
 	if (regs[0]>0x00000001) {
 		do_cpuid(0x00000001, regs2);
+		printf("CPU family: %d\n",(regs2[0] >> 8)&0xf);
 		switch ((regs2[0] >> 8)&0xf) {
 			case 3:
 				caps->cpuType=CPUTYPE_I386;
@@ -90,9 +111,11 @@
 				printf("Unknown cpu type, default to i386\n");
 				break;
 		}
-		caps->hasMMX  = (regs2[3] & (1 << 23 )) >> 23;
-		caps->hasSSE  = (regs2[3] & (1 << 25 )) >> 25;
-		caps->hasSSE2 = (regs2[3] & (1 << 26 )) >> 26;
+		caps->hasMMX  = (regs2[3] & (1 << 23 )) >> 23; // 0x0800000
+		
+		// FIXME: is this ok for non-intel CPUs too? (cyrix,amd)
+		caps->hasSSE  = (regs2[3] & (1 << 25 )) >> 25; // 0x2000000
+		caps->hasSSE2 = (regs2[3] & (1 << 26 )) >> 26; // 0x4000000
 		/* FIXME: Does SSE2 need more OS support, too? */
 #if defined(__linux__) || defined(__FreeBSD__)
 		if (caps->hasSSE)
@@ -106,15 +129,18 @@
 		/* FIXME: Are MMX2 ops on the same set of processors as SSE?  Do they need OS support?*/
 		caps->hasMMX2 = caps->hasSSE;
 	}
-	if (memcmp(&regs[1], "AuthenticAMD", 12)) {
+	if (regs[1] == 0x68747541 &&    // AuthenticAMD
+            regs[3] == 0x69746e65 &&
+            regs[2] == 0x444d4163) {
 		do_cpuid(0x80000000, regs);
-		if (regs[0]>0x80000001) {
+		if (regs[0]>=0x80000001) {
 			do_cpuid(0x80000001, regs2);
-			/*caps->hasMMX2 = regs[3] & (1 << 23 );*/
-			caps->has3DNow    = (regs2[3] & (1 << 31 )) >> 31;
+			caps->hasMMX2 = (regs[3] & (1 << 22 )) >> 22; // 0x400000
+			caps->has3DNow    = (regs2[3] & (1 << 31 )) >> 31; //0x80000000
 			caps->has3DNowExt = (regs2[3] & (1 << 30 )) >> 30;
 		}
 	}
+#if 0
 	printf("cpudetect: MMX=%d MMX2=%d SSE=%d SSE2=%d 3DNow=%d 3DNowExt=%d\n",
 		gCpuCaps.hasMMX,
 		gCpuCaps.hasMMX2,
@@ -122,6 +148,7 @@
 		gCpuCaps.hasSSE2,
 		gCpuCaps.has3DNow,
 		gCpuCaps.has3DNowExt );
+#endif
 
 }
 
@@ -203,7 +230,8 @@
    if ( gCpuCaps.hasSSE ) {
       printf( "Testing OS support for SSE... " );
 
-      __asm __volatile ("xorps %%xmm0, %%xmm0");
+//      __asm __volatile ("xorps %%xmm0, %%xmm0");
+      __asm __volatile ("xorps %xmm0, %xmm0");
 
       if ( gCpuCaps.hasSSE ) {
 	 printf( "yes.\n" );
@@ -228,7 +256,7 @@
    if ( gCpuCaps.hasSSE ) {
       printf( "Testing OS support for SSE unmasked exceptions... " );
 
-      test_os_katmai_exception_support();
+//      test_os_katmai_exception_support();
 
       if ( gCpuCaps.hasSSE ) {
 	 printf( "yes.\n" );
--- a/mplayer.c	Fri Oct 19 01:53:45 2001 +0000
+++ b/mplayer.c	Fri Oct 19 02:00:45 2001 +0000
@@ -66,6 +66,8 @@
 #include "linux/timer.h"
 #include "linux/shmem.h"
 
+#include "cpudetect.h"
+
 #ifdef HAVE_LIRC
 #include "lirc_mp.h"
 #endif
@@ -472,6 +474,15 @@
 
   mp_msg(MSGT_CPLAYER,MSGL_INFO,"%s",banner_text);
 
+  /* Test for cpu capabilities (and corresponding OS support) for optimizing */
+#ifdef ARCH_X86
+  GetCpuCaps(&gCpuCaps);
+  mp_msg(MSGT_CPLAYER,MSGL_INFO,"CPUflags: Type: %d MMX: %d MMX2: %d 3DNow: %d 3DNow2: %d SSE: %d SSE2: %d\n",
+      gCpuCaps.cpuType,gCpuCaps.hasMMX,gCpuCaps.hasMMX2,
+      gCpuCaps.has3DNow, gCpuCaps.has3DNowExt,
+      gCpuCaps.hasSSE, gCpuCaps.hasSSE2);
+#endif
+
 //  this one segfaults if running 'mplayer' (without path containing '/')
 //  if ( !strcmp( strrchr( argv[0],'/' ),"/gmplayer" ) ) appInit( argc,argv,envp );
   if ( argv[0] )