]> git.sesse.net Git - vlc/commitdiff
. a few changes in the CPU extensions detection code, borrowed from the
authorSam Hocevar <sam@videolan.org>
Tue, 16 Jan 2001 16:09:52 +0000 (16:09 +0000)
committerSam Hocevar <sam@videolan.org>
Tue, 16 Jan 2001 16:09:52 +0000 (16:09 +0000)
   kernel and from mpeg2dec. I still don't know how to detect if code
   compiled with -mcpu=pentiumpro will run, since the cpuid arcanes are
   quite obtuse to me. Perhaps we should also have a way not to load modules
   if they have been compiled with a different CPU to avoid segfaults.

include/main.h
include/tests.h
plugins/idct/idctmmx.c
plugins/idct/idctmmxext.c
plugins/yuv/video_yuvmmx.c
src/interface/main.c
src/misc/tests.c

index 26780df2b33dfc8a67e44ab8cc17f5f5e13e029b..af1d327052213d79b3aa89994e9a04d719398694 100644 (file)
@@ -39,6 +39,7 @@ typedef struct
     char **                ppsz_argv;              /* command line arguments */
     char **                ppsz_env;                /* environment variables */
     char *                 psz_arg0;         /* program name (whithout path) */
+    int                    i_cpu_capabilities;             /* CPU extensions */
 
     /* Generic settings */
     boolean_t              b_audio;             /* is audio output allowed ? */
index 047bffd23790023319d6efc9933e9e1094b07ca5..9555d0b445fb089221c0a54e4cb05b0fea251c18 100644 (file)
  *****************************************************************************/
 
 #define CPU_CAPABILITY_NONE    0
-#define CPU_CAPABILITY_MMX     1<<0
-#define CPU_CAPABILITY_3DNOW   1<<1
-#define CPU_CAPABILITY_MMXEXT  1<<2
-
-#define cpuid( a, eax, ebx, ecx, edx ) \
-    asm volatile ( "pushl %%ebx      \n\
-                    cpuid            \n\
-                    popl %%ebx"        \
-                 : "=a" ( eax ),       \
-                   "=c" ( ecx ),       \
-                   "=d" ( edx )        \
-                 : "a"  ( a )          \
-                 : "cc" );
+#define CPU_CAPABILITY_486     1<<0
+#define CPU_CAPABILITY_586     1<<1
+#define CPU_CAPABILITY_PPRO    1<<2
+#define CPU_CAPABILITY_MMX     1<<3
+#define CPU_CAPABILITY_3DNOW   1<<4
+#define CPU_CAPABILITY_MMXEXT  1<<5
 
 /*****************************************************************************
  * TestVersion: tests if the given string equals the current version
 int TestVersion( char * psz_version );
 int TestProgram( char * psz_program );
 int TestMethod( char * psz_var, char * psz_method );
+int TestCPU( int i_capabilities );
 
 /*****************************************************************************
- * TestCPU: tests if the processor has MMX support and other capabilities
+ * CPUCapabilities: list the processors MMX support and other capabilities
  *****************************************************************************
- * This function is called to check extensions the CPU may have.
+ * This function is called to list extensions the CPU may have.
  *****************************************************************************/
-static __inline__ int TestCPU( void )
+static __inline__ int CPUCapabilities( void )
 {
-#ifndef __i386__
-    return( CPU_CAPABILITY_NONE );
-#else
-    int i_reg, i_dummy = 0;
+    int         i_capabilities = CPU_CAPABILITY_NONE;
+#ifdef __i386__
+    int         i_eax, i_ebx, i_ecx, i_edx;
+    boolean_t   b_amd;
+
+#define cpuid( a )                 \
+    asm volatile ( "cpuid"         \
+                 : "=a" ( i_eax ), \
+                   "=b" ( i_ebx ), \
+                   "=c" ( i_ecx ), \
+                   "=d" ( i_edx )  \
+                 : "a"  ( a )      \
+                 : "cc" );         \
 
-    /* test for a 386 CPU */
+    /* test for a 486 CPU */
     asm volatile ( "pushfl
                     popl %%eax
-                    movl %%eax, %%ecx
-                    xorl $0x40000, %%eax
+                    movl %%eax, %%ebx
+                    xorl $0x200000, %%eax
                     pushl %%eax
                     popfl
                     pushfl
-                    popl %%eax
-                    xorl %%ecx, %%eax
-                    andl $0x40000, %%eax"
-                 : "=a" ( i_reg ) );
+                    popl %%eax"
+                 : "=a" ( i_eax ),
+                   "=b" ( i_ebx )
+                 :
+                 : "cc" );
 
-    if( !i_reg )
+    if( i_eax == i_ebx )
     {
-        return( CPU_CAPABILITY_NONE );
+        return( i_capabilities );
     }
 
-    /* test for a 486 CPU */
-    asm volatile ( "movl %%ecx, %%eax
-                    xorl $0x200000, %%eax
-                    pushl %%eax
-                    popfl
-                    pushfl
-                    popl %%eax
-                    xorl %%ecx, %%eax
-                    pushl %%ecx
-                    popfl
-                    andl $0x200000, %%eax"
-                 : "=a" ( i_reg ) );
+    i_capabilities |= CPU_CAPABILITY_486;
+
+    /* the CPU supports the CPUID instruction - get its level */
+    cpuid( 0x00000000 );
 
-    if( !i_reg )
+    if( !i_eax )
     {
-        return( CPU_CAPABILITY_NONE );
+        return( i_capabilities );
     }
 
-    /* the CPU supports the CPUID instruction - get its level */
-    cpuid( 0, i_reg, i_dummy, i_dummy, i_dummy );
+    /* FIXME: this isn't correct, since some 486s have cpuid */
+    i_capabilities |= CPU_CAPABILITY_586;
+
+    /* borrowed from mpeg2dec */
+    b_amd = ( i_ebx == 0x68747541 ) && ( i_ecx == 0x444d4163 )
+                    && ( i_edx == 0x69746e65 );
+
+    /* test for the MMX flag */
+    cpuid( 0x00000001 );
 
-    if( !i_reg )
+    if( ! (i_edx & 0x00800000) )
     {
-        return( CPU_CAPABILITY_NONE );
+        return( i_capabilities );
     }
 
-    /* test for the MMX flag */
-    cpuid( 1, i_dummy, i_dummy, i_dummy, i_reg );
+    i_capabilities |= CPU_CAPABILITY_MMX;
+
+    if( i_edx & 0x02000000 )
+    {
+        i_capabilities |= CPU_CAPABILITY_MMXEXT;
+    }
+    
+    /* test for additional capabilities */
+    cpuid( 0x80000000 );
+
+    if( i_eax < 0x80000001 )
+    {
+        return( i_capabilities );
+    }
+
+    /* list these additional capabilities */
+    cpuid( 0x80000001 );
+
+    if( i_edx & 0x80000000 )
+    {
+        i_capabilities |= CPU_CAPABILITY_3DNOW;
+    }
 
-    if( ! (i_reg & 0x00800000) )
+    if( b_amd && ( i_edx & 0x00400000 ) )
     {
-        return( CPU_CAPABILITY_NONE );
+        i_capabilities |= CPU_CAPABILITY_MMXEXT;
     }
+#endif /* __i386__ */
 
-    return( CPU_CAPABILITY_MMX );
-#endif
+    return( i_capabilities );
 }
 
index f120e2281bf684f922f9fc28f7ed1ddf9e8c0155..4457bb865090dda36c4643117ff0c7464bae3824 100644 (file)
@@ -2,7 +2,7 @@
  * idctmmx.c : MMX IDCT module
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: idctmmx.c,v 1.4 2001/01/16 05:04:25 sam Exp $
+ * $Id: idctmmx.c,v 1.5 2001/01/16 16:09:52 sam Exp $
  *
  * Authors: GaĆ«l Hendryckx <jimmy@via.ecp.fr>
  *
@@ -143,7 +143,7 @@ static void idct_getfunctions( function_list_t * p_function_list )
  *****************************************************************************/
 static int idct_Probe( probedata_t *p_data )
 {
-    if( TestCPU() & CPU_CAPABILITY_MMX )
+    if( TestCPU( CPU_CAPABILITY_MMX ) )
     {
         if( TestMethod( IDCT_METHOD_VAR, "idctmmx" ) )
         {
index 59475025f083af70c7c66e463b271d441676eaec..f09005c3b4f43b0fa301b6e9c1599cf0bc247d22 100644 (file)
@@ -2,7 +2,7 @@
  * idctmmxext.c : MMX EXT IDCT module
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: idctmmxext.c,v 1.2 2001/01/16 14:05:38 sam Exp $
+ * $Id: idctmmxext.c,v 1.3 2001/01/16 16:09:52 sam Exp $
  *
  * Authors:
  *
@@ -143,7 +143,7 @@ static void idct_getfunctions( function_list_t * p_function_list )
  *****************************************************************************/
 static int idct_Probe( probedata_t *p_data )
 {
-    if( TestCPU() & CPU_CAPABILITY_MMXEXT )
+    if( 0/*TestCPU( CPU_CAPABILITY_MMXEXT )*/ )
     {
         if( TestMethod( IDCT_METHOD_VAR, "idctmmxext" ) )
         {
index 2d72f51dcdd8f036a5c5fa35412624236ad98da5..f7e72990cbcc937b3754bd5774a2249c599e1477 100644 (file)
@@ -75,7 +75,7 @@ void yuv_getfunctions( function_list_t * p_function_list )
 static int yuv_Probe( probedata_t *p_data )
 {
     /* Test for MMX support in the CPU */
-    if( TestCPU() & CPU_CAPABILITY_MMX )
+    if( TestCPU( CPU_CAPABILITY_MMX ) )
     {
         if( TestMethod( YUV_METHOD_VAR, "yuvmmx" ) )
         {
index adec47184e588b34ca7babce7c7e9be0d26d21bd..1e4df4711d6363e3c68f36eef7c6f20fcb98bedd 100644 (file)
@@ -191,14 +191,25 @@ int main( int i_argc, char *ppsz_argv[], char *ppsz_env[] )
     beos_Create();
 #endif
 
+    p_main->i_cpu_capabilities = CPUCapabilities();
+
     /*
      * Test if our code is likely to run on this CPU 
      */
+#if defined( __pentium__ ) || defined( __pentiumpro__ )
+    if( ! TestCPU( CPU_CAPABILITY_586 ) )
+    {
+        fprintf( stderr, "Sorry, this program needs a Pentium CPU.\n"
+                         "Please try a version without Pentium support.\n" );
+        return( 1 );
+    }
+#endif
+
 #ifdef HAVE_MMX
-    if( !( TestCPU() & CPU_CAPABILITY_MMX ) )
+    if( ! TestCPU( CPU_CAPABILITY_MMX ) )
     {
-        fprintf( stderr, "Sorry, this program needs an MMX processor. "
-                         "Please run the non-MMX version.\n" );
+        fprintf( stderr, "Sorry, this program needs MMX extensions.\n"
+                         "Please try a version without MMX support.\n" );
         return( 1 );
     }
 #endif
index 25fae290a4b47b26709eaada82f5553b1b49038c..b16f54cb6003cddabeaaa12797b79e5f9b8a9738 100644 (file)
@@ -58,3 +58,11 @@ int TestMethod( char * psz_var, char * psz_method )
     return( !strcmp( psz_method, main_GetPszVariable( psz_var, "" ) ) );
 }
 
+/*****************************************************************************
+ * TestCPU: tests if the processor has MMX support and other capabilities
+ *****************************************************************************/
+int TestCPU( int i_capabilities )
+{
+    return( (i_capabilities & p_main->i_cpu_capabilities) == i_capabilities );
+}
+