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

Run-time CPU detection for ARM (meaning NEON)

Unfortunately, we cannot emit NEON opcodes when NEON is not explicitly
enabled (-mfpu=neon), contrary to MMX & SSE on x86. As a consequence,
this will not work for inline assembler in a non-optimized plugin,
namely the deinterlacer.

There is also a(n hopefully theoretical) bug whereby the compiler would
emit NEON instructions in the descriptor or activation callback of a
NEON plugin. This could then crash if NEON is not supported, even
before the NEON run-time check is reached.
parent d809a540
...@@ -1489,12 +1489,16 @@ asm volatile("ssat r0, #1, r0":::"r0"); /* assume ARMv6 */ ...@@ -1489,12 +1489,16 @@ asm volatile("ssat r0, #1, r0":::"r0"); /* assume ARMv6 */
]) ])
CFLAGS="${CFLAGS_save}" CFLAGS="${CFLAGS_save}"
]) ])
ARM_NEON_CFLAGS="$ac_cv_neon_inline" AS_IF([test "$ac_cv_neon_inline" != "no"], [
NEON_CFLAGS="$ac_cv_neon_inline"
AC_DEFINE([CAN_COMPILE_NEON], 1,
[Define to 1 if NEON (and ARMv6) assembly is available with NEON_CFLAGS.])
])
], [ ], [
ac_cv_neon_inline="no" ac_cv_neon_inline="no"
]) ])
AC_SUBST(ARM_NEON_CFLAGS) AC_SUBST(NEON_CFLAGS)
AM_CONDITIONAL(HAVE_ARM_NEON, [test "${ac_cv_neon_inline}" != "no"]) AM_CONDITIONAL(HAVE_NEON, [test "${ac_cv_neon_inline}" != "no"])
AC_ARG_ENABLE(altivec, AC_ARG_ENABLE(altivec,
......
...@@ -51,7 +51,7 @@ endif ...@@ -51,7 +51,7 @@ endif
if HAVE_ALTIVEC if HAVE_ALTIVEC
SUBDIRS += altivec SUBDIRS += altivec
endif endif
if HAVE_ARM_NEON if HAVE_NEON
SUBDIRS += arm_neon SUBDIRS += arm_neon
endif endif
if BUILD_LUA if BUILD_LUA
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
# without this. (This is the case with iOS). # without this. (This is the case with iOS).
LIBTOOL=@LIBTOOL@ --tag=CC LIBTOOL=@LIBTOOL@ --tag=CC
AM_CFLAGS += $(ARM_NEON_CFLAGS) AM_CFLAGS += $(NEON_CFLAGS)
libaudio_format_neon_plugin_la_SOURCES = \ libaudio_format_neon_plugin_la_SOURCES = \
s32_s16.S \ s32_s16.S \
......
...@@ -682,7 +682,7 @@ int Open( vlc_object_t *p_this ) ...@@ -682,7 +682,7 @@ int Open( vlc_object_t *p_this )
} }
else else
#endif #endif
#if defined __ARM_NEON__ #if defined __ARM_NEON__ // FIXME: runtime detect support
if( vlc_CPU() & CPU_CAPABILITY_NEON ) if( vlc_CPU() & CPU_CAPABILITY_NEON )
{ {
p_sys->pf_merge = MergeNEON; p_sys->pf_merge = MergeNEON;
......
...@@ -247,9 +247,41 @@ uint32_t CPUCapabilities( void ) ...@@ -247,9 +247,41 @@ uint32_t CPUCapabilities( void )
} }
out: out:
#elif defined( __arm__ ) #elif defined (__arm__)
# if defined( __ARM_NEON__ )
# if defined (__ARM_NEON__)
i_capabilities |= CPU_CAPABILITY_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 # endif
#elif defined( __powerpc__ ) || defined( __ppc__ ) || defined( __powerpc64__ ) \ #elif defined( __powerpc__ ) || defined( __ppc__ ) || defined( __powerpc64__ ) \
......
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