Commit b821b669 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

Set VLC_MMX and VLC_SSE where needed while testing the CPU features

parent 96447a8a
...@@ -51,45 +51,91 @@ ...@@ -51,45 +51,91 @@
static uint32_t cpu_flags; static uint32_t cpu_flags;
#if defined( __i386__ ) || defined( __x86_64__ ) || defined( __powerpc__ ) \ #if defined (__i386__) || defined (__x86_64__) || defined (__powerpc__) \
|| defined( __ppc__ ) || defined( __ppc64__ ) || defined( __powerpc64__ ) || defined (__ppc__) || defined (__ppc64__) || defined (__powerpc64__)
# if !defined( WIN32 ) && !defined( __OS2__ ) # if !defined (WIN32) && !defined (__OS2__)
static bool check_OS_capability( const char *psz_capability, pid_t pid ) static bool vlc_CPU_check (const char *name, void (*func) (void))
{ {
int status; pid_t pid = fork();
if( pid == -1 ) switch (pid)
return false; /* fail safe :-/ */ {
case 0:
signal (SIGILL, SIG_DFL);
func ();
//__asm__ __volatile__ ( code : : input );
_exit (0);
case -1:
return false;
}
//i_capabilities |= (flag);
int status;
while( waitpid( pid, &status, 0 ) == -1 ); while( waitpid( pid, &status, 0 ) == -1 );
if( WIFEXITED( status ) && WEXITSTATUS( status ) == 0 ) if( WIFEXITED( status ) && WEXITSTATUS( status ) == 0 )
return true; return true;
fprintf( stderr, "warning: your CPU has %s instructions, but not your " fprintf (stderr, "Warning: your CPU has %s instructions, but not your "
"operating system.\n", psz_capability ); "operating system.\n", name);
fprintf( stderr, " some optimizations will be disabled unless " fprintf( stderr, " some optimizations will be disabled unless "
"you upgrade your OS\n" ); "you upgrade your OS\n" );
return false; return false;
} }
# define check_capability(name, flag, code, input) \ #if defined (CAN_COMPILE_SSE) && !defined (__SSE__)
do { \ VLC_SSE static void SSE_test (void)
pid_t pid = fork(); \ {
if( pid == 0 ) \ asm volatile ("xorps %%xmm0,%%xmm0\n" : : : "xmm0", "xmm1");
{ \ }
signal(SIGILL, SIG_DFL); \ #endif
__asm__ __volatile__ ( code : : input ); \ #if defined (CAN_COMPILE_SSE2) && !defined (__SSE2__)
_exit(0); \ VLC_SSE static void SSE2_test (void)
} \ {
if( check_OS_capability((name), pid )) \ asm volatile ("movupd %%xmm0, %%xmm0\n" : : : "xmm0", "xmm1");
i_capabilities |= (flag); \ }
} while(0) #endif
#if defined (CAN_COMPILE_SSE3) && !defined (__SSE3__)
# else /* WIN32 || __OS2__ */ VLC_SSE static void SSE3_test (void)
# define check_capability(name, flag, code, input) \ {
i_capabilities |= (flag); asm volatile ("movsldup %%xmm1, %%xmm0\n" : : : "xmm0", "xmm1");
# endif }
#endif
#if defined (CAN_COMPILE_SSSE3) && !defined (__SSSE3__)
VLC_SSE static void SSSE3_test (void)
{
asm volatile ("pabsw %%xmm1, %%xmm0\n" : : : "xmm0", "xmm1");
}
#endif
#if defined (CAN_COMPILE_SSE4_1) && !defined (__SSE4_1__)
VLC_SSE static void SSE4_1_test (void)
{
asm volatile ("pmaxsb %%xmm1, %%xmm0\n" : : : "xmm0", "xmm1");
}
#endif
#if defined (CAN_COMPILE_SSE4_2) && !defined (__SSE4_2__)
VLC_SSE static void SSE4_2_test (void)
{
asm volatile ("pcmpgtq %%xmm1, %%xmm0\n" : : : "xmm0", "xmm1");
}
#endif
#if defined (CAN_COMPILE_3DNOW) && !defined (__3dNOW__)
VLC_MMX static void ThreeD_Now_test (void)
{
asm volatile ("pfadd %%mm0,%%mm0\n" "femms\n" : : : "mm0");
}
#endif
#if defined (CAN_COMPILE_ALTIVEC)
static void Altivec_text (void)
{
asm volatile ("mtspr 256, %0\n" "vand %%v0, %%v0, %%v0\n" : : "r" (-1));
}
#endif
#else /* WIN32 || __OS2__ */
# define vlc_CPU_check(name, func) (1)
#endif
#endif #endif
/** /**
...@@ -175,8 +221,8 @@ void vlc_CPU_init (void) ...@@ -175,8 +221,8 @@ void vlc_CPU_init (void)
i_capabilities |= CPU_CAPABILITY_MMXEXT; i_capabilities |= CPU_CAPABILITY_MMXEXT;
# ifdef CAN_COMPILE_SSE # ifdef CAN_COMPILE_SSE
check_capability( "SSE", CPU_CAPABILITY_SSE, if (vlc_CPU_check ("SSE", SSE_test))
"xorps %%xmm0,%%xmm0\n", ); i_capabilities |= CPU_CAPABILITY_SSE;
# endif # endif
} }
# endif # endif
...@@ -184,41 +230,36 @@ void vlc_CPU_init (void) ...@@ -184,41 +230,36 @@ void vlc_CPU_init (void)
# if defined (__SSE2__) # if defined (__SSE2__)
i_capabilities |= CPU_CAPABILITY_SSE2; i_capabilities |= CPU_CAPABILITY_SSE2;
# elif defined (CAN_COMPILE_SSE2) # elif defined (CAN_COMPILE_SSE2)
if( i_edx & 0x04000000 ) if ((i_edx & 0x04000000) && vlc_CPU_check ("SSE2", SSE2_test))
check_capability( "SSE2", CPU_CAPABILITY_SSE2, i_capabilities |= CPU_CAPABILITY_SSE2;
"movupd %%xmm0, %%xmm0\n", );
# endif # endif
# if defined (__SSE3__) # if defined (__SSE3__)
i_capabilities |= CPU_CAPABILITY_SSE3; i_capabilities |= CPU_CAPABILITY_SSE3;
# elif defined (CAN_COMPILE_SSE3) # elif defined (CAN_COMPILE_SSE3)
if( i_ecx & 0x00000001 ) if ((i_ecx & 0x00000001) && vlc_CPU_check ("SSE3", SSE3_test))
check_capability( "SSE3", CPU_CAPABILITY_SSE3, i_capabilities |= CPU_CAPABILITY_SSE3;
"movsldup %%xmm1, %%xmm0\n", );
# endif # endif
# if defined (__SSSE3__) # if defined (__SSSE3__)
i_capabilities |= CPU_CAPABILITY_SSSE3; i_capabilities |= CPU_CAPABILITY_SSSE3;
# elif defined (CAN_COMPILE_SSSE3) # elif defined (CAN_COMPILE_SSSE3)
if( i_ecx & 0x00000200 ) if ((i_ecx & 0x00000200) && vlc_CPU_check ("SSSE3", SSSE3_test))
check_capability( "SSSE3", CPU_CAPABILITY_SSSE3, i_capabilities |= CPU_CAPABILITY_SSSE3;
"pabsw %%xmm1, %%xmm0\n", );
# endif # endif
# if defined (__SSE4_1__) # if defined (__SSE4_1__)
i_capabilities |= CPU_CAPABILITY_SSE4_1; i_capabilities |= CPU_CAPABILITY_SSE4_1;
# elif defined (CAN_COMPILE_SSE4_1) # elif defined (CAN_COMPILE_SSE4_1)
if( i_ecx & 0x00080000 ) if ((i_ecx & 0x00080000) && vlc_CPU_check ("SSE4.1", SSE4_1_test))
check_capability( "SSE4.1", CPU_CAPABILITY_SSE4_1, i_capabilities |= CPU_CAPABILITY_SSE4_1;
"pmaxsb %%xmm1, %%xmm0\n", );
# endif # endif
# if defined (__SSE4_2__) # if defined (__SSE4_2__)
i_capabilities |= CPU_CAPABILITY_SSE4_2; i_capabilities |= CPU_CAPABILITY_SSE4_2;
# elif defined (CAN_COMPILE_SSE4_2) # elif defined (CAN_COMPILE_SSE4_2)
if( i_ecx & 0x00100000 ) if ((i_ecx & 0x00100000) && vlc_CPU_check ("SSE4.2", SSE4_2_test))
check_capability( "SSE4.2", CPU_CAPABILITY_SSE4_2, i_capabilities |= CPU_CAPABILITY_SSE4_2;
"pcmpgtq %%xmm1, %%xmm0\n", );
# endif # endif
/* test for additional capabilities */ /* test for additional capabilities */
...@@ -233,9 +274,8 @@ void vlc_CPU_init (void) ...@@ -233,9 +274,8 @@ void vlc_CPU_init (void)
# if defined (__3dNOW__) # if defined (__3dNOW__)
i_capabilities |= CPU_CAPABILITY_3DNOW; i_capabilities |= CPU_CAPABILITY_3DNOW;
# elif defined (CAN_COMPILE_3DNOW) # elif defined (CAN_COMPILE_3DNOW)
if( i_edx & 0x80000000 ) if ((i_edx & 0x80000000) && vlc_CPU_check ("3D Now!", ThreeD_Now_test))
check_capability( "3D Now!", CPU_CAPABILITY_3DNOW, i_capabilities |= CPU_CAPABILITY_3DNOW;
"pfadd %%mm0,%%mm0\n" "femms\n", );
# endif # endif
if( b_amd && ( i_edx & 0x00400000 ) ) if( b_amd && ( i_edx & 0x00400000 ) )
...@@ -300,10 +340,8 @@ out: ...@@ -300,10 +340,8 @@ out:
i_capabilities |= CPU_CAPABILITY_ALTIVEC; i_capabilities |= CPU_CAPABILITY_ALTIVEC;
# elif defined( CAN_COMPILE_ALTIVEC ) # elif defined( CAN_COMPILE_ALTIVEC )
check_capability( "Altivec", CPU_CAPABILITY_ALTIVEC, if (vlc_CPU_check ("Altivec", Altivec_test))
"mtspr 256, %0\n\t" i_capabilities |= CPU_CAPABILITY_ALTIVEC;
"vand %%v0, %%v0, %%v0",
"r" (-1));
# endif # endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment