]> git.sesse.net Git - vlc/blobdiff - src/misc/cpu.c
aout_PacketPlay: use aout_TimeReport(), restore resampling
[vlc] / src / misc / cpu.c
index 3640865e9ccaa6d4c8619054c6cf0883fcdc0934..20520d20b03186fef2d43fcdda3bd42867398bc9 100644 (file)
 #include <signal.h>
 #else
 #include <errno.h>
-#include <windows.h>
-#include <winbase.h>
-#define PF_SSE3_INSTRUCTIONS_AVAILABLE 13
 #endif
+#include <assert.h>
 
-#include "libvlc.h"
-
-#if defined(__APPLE__) && (defined(__ppc__) || defined(__ppc64__))
+#ifdef __APPLE__
 #include <sys/sysctl.h>
 #endif
 
+#include "libvlc.h"
+
 #if defined( __i386__ ) || defined( __x86_64__ ) || defined( __powerpc__ ) \
  || defined( __ppc__ ) || defined( __ppc64__ ) || defined( __powerpc64__ )
 # ifndef WIN32
@@ -88,9 +86,7 @@ static bool check_OS_capability( const char *psz_capability, pid_t pid )
 
 # else /* WIN32 */
 #  define check_capability(name, flag, code)   \
-     do {                                      \
-        i_capabilities |= (flag);              \
-     } while(0)
+        i_capabilities |= (flag);
 # endif
 #endif
 
@@ -172,12 +168,12 @@ uint32_t CPUCapabilities( void )
 
     /* test for the MMX flag */
     cpuid( 0x00000001 );
-
 # if !defined (__MMX__)
     if( ! (i_edx & 0x00800000) )
         goto out;
 # endif
     i_capabilities |= CPU_CAPABILITY_MMX;
+
 # if defined (__SSE__)
     i_capabilities |= CPU_CAPABILITY_MMXEXT | CPU_CAPABILITY_SSE;
 # else
@@ -186,13 +182,8 @@ uint32_t CPUCapabilities( void )
         i_capabilities |= CPU_CAPABILITY_MMXEXT;
 
 #   ifdef CAN_COMPILE_SSE
-#   ifdef WIN32
-        if( IsProcessorFeaturePresent( PF_XMMI_INSTRUCTIONS_AVAILABLE ) )
-            i_capabilities |= CPU_CAPABILITY_SSE;
-#   else
         check_capability( "SSE", CPU_CAPABILITY_SSE,
                           "xorps %%xmm0,%%xmm0\n" );
-#   endif
 #   endif
     }
 # endif
@@ -201,66 +192,40 @@ uint32_t CPUCapabilities( void )
     i_capabilities |= CPU_CAPABILITY_SSE2;
 # elif defined (CAN_COMPILE_SSE2)
     if( i_edx & 0x04000000 )
-    {
-#   ifdef WIN32
-        if( IsProcessorFeaturePresent( PF_XMMI64_INSTRUCTIONS_AVAILABLE ) )
-            i_capabilities |= CPU_CAPABILITY_SSE2;
-#   else
         check_capability( "SSE2", CPU_CAPABILITY_SSE2,
                           "movupd %%xmm0, %%xmm0\n" );
-#   endif
-    }
 # endif
 
 # if defined (__SSE3__)
     i_capabilities |= CPU_CAPABILITY_SSE3;
 # elif defined (CAN_COMPILE_SSE3)
     if( i_ecx & 0x00000001 )
-    {
-#   ifdef WIN32
-        if( IsProcessorFeaturePresent( PF_SSE3_INSTRUCTIONS_AVAILABLE ) )
-            i_capabilities |= CPU_CAPABILITY_SSE3;
-#   else
         check_capability( "SSE3", CPU_CAPABILITY_SSE3,
                           "movsldup %%xmm1, %%xmm0\n" );
-#   endif
-    }
 # endif
 
 # if defined (__SSSE3__)
     i_capabilities |= CPU_CAPABILITY_SSSE3;
 # elif defined (CAN_COMPILE_SSSE3)
-#   ifdef WIN32
-    /* FIXME: IsProcessorFeaturePresent can't check for SSSE3 */
-#   else
     if( i_ecx & 0x00000200 )
         check_capability( "SSSE3", CPU_CAPABILITY_SSSE3,
                           "pabsw %%xmm1, %%xmm0\n" );
-#   endif
 # endif
 
 # if defined (__SSE4_1__)
     i_capabilities |= CPU_CAPABILITY_SSE4_1;
 # elif defined (CAN_COMPILE_SSE4_1)
-#   ifdef WIN32
-    /* FIXME: IsProcessorFeaturePresent can't check for SSE4.1 */
-#   else
     if( i_ecx & 0x00080000 )
         check_capability( "SSE4.1", CPU_CAPABILITY_SSE4_1,
                           "pmaxsb %%xmm1, %%xmm0\n" );
-#   endif
 # endif
 
 # if defined (__SSE4_2__)
     i_capabilities |= CPU_CAPABILITY_SSE4_2;
 # elif defined (CAN_COMPILE_SSE4_2)
-#   ifdef WIN32
-    /* FIXME: IsProcessorFeaturePresent can't check for SSE4.2 */
-#   else
     if( i_ecx & 0x00100000 )
         check_capability( "SSE4.2", CPU_CAPABILITY_SSE4_2,
                           "pcmpgtq %%xmm1, %%xmm0\n" );
-#   endif
 # endif
 
     /* test for additional capabilities */
@@ -275,17 +240,9 @@ uint32_t CPUCapabilities( void )
 # if defined (__3dNOW__)
     i_capabilities |= CPU_CAPABILITY_3DNOW;
 # elif defined (CAN_COMPILE_3DNOW)
-
     if( i_edx & 0x80000000 )
-    {
-#   ifdef WIN32
-        if( IsProcessorFeaturePresent( PF_3DNOW_INSTRUCTIONS_AVAILABLE ) )
-            i_capabilities |= CPU_CAPABILITY_3DNOW;
-#   else
         check_capability( "3D Now!", CPU_CAPABILITY_3DNOW,
                           "pfadd %%mm0,%%mm0\n" "femms\n" );
-#   endif
-    }
 # endif
 
     if( b_amd && ( i_edx & 0x00400000 ) )
@@ -294,16 +251,52 @@ uint32_t CPUCapabilities( void )
     }
 out:
 
-#elif defined( __arm__ )
-#   if defined( __ARM_NEON__ )
+#elif defined (__arm__)
+
+# if defined (__ARM_NEON__)
     i_capabilities |= CPU_CAPABILITY_NEON;
+# elif defined (CAN_COMPILE_NEON)
+#  define NEED_RUNTIME_CPU_CHECK 1
+# endif
+
+# ifdef NEED_RUNTIME_CPU_CHECK
+#  if defined (__linux__)
+    FILE *info = fopen ("/proc/cpuinfo", "rt");
+    if (info != NULL)
+    {
+        char *line = NULL;
+        size_t linelen = 0;
+
+        while (getline (&line, &linelen, info) != -1)
+        {
+             const char *cap;
+
+             if (strncmp (line, "Features\t:", 10))
+                 continue;
+#   if defined (CAN_COMPILE_NEON) && !defined (__ARM_NEON__)
+             cap = strstr (line + 10, " neon");
+             if (cap != NULL && (cap[5] == '\0' || cap[5] == ' '))
+                 i_capabilities |= CPU_CAPABILITY_NEON;
 #   endif
+             break;
+        }
+        fclose (info);
+        free (line);
+    }
+#  else
+#   warning Run-time CPU detection missing: optimizations disabled!
+#  endif
+# endif
 
 #elif defined( __powerpc__ ) || defined( __ppc__ ) || defined( __powerpc64__ ) \
     || defined( __ppc64__ )
 
-#   if defined(__APPLE__)
+#   if defined(__APPLE__) || defined(__OpenBSD__)
+#   if defined(__OpenBSD__)
+    int selectors[2] = { CTL_MACHDEP, CPU_ALTIVEC };
+#   else
     int selectors[2] = { CTL_HW, HW_VECTORUNIT };
+#   endif
     int i_has_altivec = 0;
     size_t i_length = sizeof( i_has_altivec );
     int i_error = sysctl( selectors, 2, &i_has_altivec, &i_length, NULL, 0);
@@ -343,57 +336,12 @@ unsigned vlc_CPU (void)
     return cpu_flags;
 }
 
-const struct
-{
-    uint32_t value;
-    char name[12];
-} cap_dirs[] = {
-#if defined ( __i386__ ) || defined ( __x86_64__ )
-    { CPU_CAPABILITY_MMX,     "mmx" },
-    { CPU_CAPABILITY_MMXEXT,  "mmxext" },
-    { CPU_CAPABILITY_3DNOW,   "3dnow" },
-    { CPU_CAPABILITY_SSE,     "sse" },
-#endif
-#if defined (__ppc__) || defined (__ppc64__) || defined (__powerpc__)
-    { CPU_CAPABILITY_ALTIVEC, "altivec" },
-#endif
-#if defined (__arm__)
-    { CPU_CAPABILITY_NEON,    "arm_neon" },
-#endif
-};
-
-/**
- * Check if a directory name contains usable plugins w.r.t. the hardware
- * capabilities. Loading a plugin when the hardware has insufficient
- * capabilities may lead to illegal instructions (SIGILL) and must be avoided.
- *
- * @param name the name of the directory (<b>not</b> the path)
- *
- * @return true if the hardware has sufficient capabilities or the directory
- * does not require any special capability; false if the running hardware has
- * insufficient capabilities.
- */
-bool vlc_CPU_CheckPluginDir (const char *name)
-{
-    const unsigned flags = vlc_CPU ();
-    for (size_t i = 0; i < sizeof (cap_dirs) / sizeof (cap_dirs[0]); i++)
-    {
-        if (strcmp (name, cap_dirs[i].name))
-            continue;
-        return (flags & cap_dirs[i].value) != 0;
-    }
-    return true;
-}
-
 static vlc_memcpy_t pf_vlc_memcpy = memcpy;
-static vlc_memset_t pf_vlc_memset = memset;
 
-void vlc_fastmem_register (vlc_memcpy_t cpy, vlc_memset_t set)
+void vlc_fastmem_register (vlc_memcpy_t cpy)
 {
-    if (cpy)
-        pf_vlc_memcpy = cpy;
-    if (set)
-        pf_vlc_memset = set;
+    assert (cpy != NULL);
+    pf_vlc_memcpy = cpy;
 }
 
 /**
@@ -405,9 +353,29 @@ void *vlc_memcpy (void *tgt, const void *src, size_t n)
 }
 
 /**
- * vlc_memset: fast CPU-dependent memset
+ * Returned an aligned pointer on newly allocated memory.
+ * \param alignment must be a power of 2 and a multiple of sizeof(void*)
+ * \param size is the size of the usable memory returned.
+ *
+ * It must not be freed directly, *base must.
  */
-void *vlc_memset (void *tgt, int c, size_t n)
+void *vlc_memalign(void **base, size_t alignment, size_t size)
 {
-    return pf_vlc_memset (tgt, c, n);
+    assert(alignment >= sizeof(void*));
+    for (size_t t = alignment; t > 1; t >>= 1)
+        assert((t&1) == 0);
+#if defined(HAVE_POSIX_MEMALIGN)
+    if (posix_memalign(base, alignment, size)) {
+        *base = NULL;
+        return NULL;
+    }
+    return *base;
+#elif defined(HAVE_MEMALIGN)
+    return *base = memalign(alignment, size);
+#else
+    unsigned char *p = *base = malloc(size + alignment - 1);
+    if (!p)
+        return NULL;
+    return (void*)((uintptr_t)(p + alignment - 1) & ~(alignment - 1));
+#endif
 }