summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJanne Grunau <janne-libav@jannau.net>2015-12-09 22:28:36 +0100
committerJanne Grunau <janne-libav@jannau.net>2015-12-14 16:42:35 +0100
commite2710e790c09e49e86baa58c6063af0097cc8cb0 (patch)
tree4bf42a3192ea353305d8409d085522100a16b350
parent5dfe4edad63971d669ae456b0bc40ef9364cca80 (diff)
arm: add a cpu flag for the VFPv2 vector mode
The vector mode was deprecated in ARMv7-A/VFPv3 and various cpu implementations do not support it in hardware. Vector mode code will depending the OS either be emulated in software or result in an illegal instruction on cpus which does not support it. This was not really problem in practice since NEON implementations of the same functions are preferred. It will however become a problem for checkasm which tests every cpu flag separately. Since this is a cpu feature newer cpu do not support anymore the behaviour of this flag differs from the other flags. It can be only activated by runtime cpu feature selection.
-rw-r--r--libavcodec/arm/dcadsp_init_arm.c4
-rw-r--r--libavcodec/arm/fft_init_arm.c2
-rw-r--r--libavcodec/arm/fmtconvert_init_arm.c2
-rw-r--r--libavutil/arm/cpu.c4
-rw-r--r--libavutil/arm/cpu.h5
-rw-r--r--libavutil/cpu.c2
-rw-r--r--libavutil/cpu.h1
-rw-r--r--libavutil/version.h2
-rw-r--r--tests/checkasm/checkasm.c1
9 files changed, 18 insertions, 5 deletions
diff --git a/libavcodec/arm/dcadsp_init_arm.c b/libavcodec/arm/dcadsp_init_arm.c
index 540048415f..252f4aeadd 100644
--- a/libavcodec/arm/dcadsp_init_arm.c
+++ b/libavcodec/arm/dcadsp_init_arm.c
@@ -59,7 +59,7 @@ av_cold void ff_dcadsp_init_arm(DCADSPContext *s)
{
int cpu_flags = av_get_cpu_flags();
- if (have_vfp(cpu_flags) && !have_vfpv3(cpu_flags)) {
+ if (have_vfp_vm(cpu_flags)) {
s->lfe_fir[0] = ff_dca_lfe_fir32_vfp;
s->lfe_fir[1] = ff_dca_lfe_fir64_vfp;
s->qmf_32_subbands = ff_dca_qmf_32_subbands_vfp;
@@ -75,7 +75,7 @@ av_cold void ff_synth_filter_init_arm(SynthFilterContext *s)
{
int cpu_flags = av_get_cpu_flags();
- if (have_vfp(cpu_flags) && !have_vfpv3(cpu_flags))
+ if (have_vfp_vm(cpu_flags))
s->synth_filter_float = ff_synth_filter_float_vfp;
if (have_neon(cpu_flags))
s->synth_filter_float = ff_synth_filter_float_neon;
diff --git a/libavcodec/arm/fft_init_arm.c b/libavcodec/arm/fft_init_arm.c
index bc143c10fb..6d6fa220a5 100644
--- a/libavcodec/arm/fft_init_arm.c
+++ b/libavcodec/arm/fft_init_arm.c
@@ -40,7 +40,7 @@ av_cold void ff_fft_init_arm(FFTContext *s)
{
int cpu_flags = av_get_cpu_flags();
- if (have_vfp(cpu_flags) && !have_vfpv3(cpu_flags)) {
+ if (have_vfp_vm(cpu_flags)) {
s->fft_calc = ff_fft_calc_vfp;
#if CONFIG_MDCT
s->imdct_half = ff_imdct_half_vfp;
diff --git a/libavcodec/arm/fmtconvert_init_arm.c b/libavcodec/arm/fmtconvert_init_arm.c
index 27d3c88011..6a80bfb6b3 100644
--- a/libavcodec/arm/fmtconvert_init_arm.c
+++ b/libavcodec/arm/fmtconvert_init_arm.c
@@ -38,7 +38,7 @@ av_cold void ff_fmt_convert_init_arm(FmtConvertContext *c, AVCodecContext *avctx
{
int cpu_flags = av_get_cpu_flags();
- if (have_vfp(cpu_flags)) {
+ if (have_vfp_vm(cpu_flags)) {
if (!have_vfpv3(cpu_flags)) {
c->int32_to_float_fmul_scalar = ff_int32_to_float_fmul_scalar_vfp;
c->int32_to_float_fmul_array8 = ff_int32_to_float_fmul_array8_vfp;
diff --git a/libavutil/arm/cpu.c b/libavutil/arm/cpu.c
index 8bdaa88469..2effb72610 100644
--- a/libavutil/arm/cpu.c
+++ b/libavutil/arm/cpu.c
@@ -131,6 +131,10 @@ int ff_get_cpu_flags_arm(void)
if (flags & AV_CPU_FLAG_ARMV6T2)
flags |= AV_CPU_FLAG_ARMV6;
+ /* set the virtual VFPv2 vector mode flag */
+ if ((flags & AV_CPU_FLAG_VFP) && !(flags & (AV_CPU_FLAG_VFPV3 | AV_CPU_FLAG_NEON)))
+ flags |= AV_CPU_FLAG_VFP_VM;
+
return flags;
}
diff --git a/libavutil/arm/cpu.h b/libavutil/arm/cpu.h
index 224409afee..5563fc1c69 100644
--- a/libavutil/arm/cpu.h
+++ b/libavutil/arm/cpu.h
@@ -30,6 +30,11 @@
#define have_vfpv3(flags) CPUEXT(flags, VFPV3)
#define have_neon(flags) CPUEXT(flags, NEON)
+/* some functions use the VFPv2 vector mode which is deprecated in ARMv7-A
+ * and might trap on such CPU depending on the OS configuration */
+#define have_vfp_vm(flags) \
+ (have_armv6(flags) && ((flags) & AV_CPU_FLAG_VFP_VM))
+
/* Some functions use the 'setend' instruction which is deprecated on ARMv8
* and serializing on some ARMv7 cores. This macro ensures such functions
* are only enabled on ARMv6. */
diff --git a/libavutil/cpu.c b/libavutil/cpu.c
index e24b9dd679..5f04461f6b 100644
--- a/libavutil/cpu.c
+++ b/libavutil/cpu.c
@@ -124,6 +124,7 @@ int av_parse_cpu_flags(const char *s)
{ "armv6", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ARMV6 }, .unit = "flags" },
{ "armv6t2", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ARMV6T2 }, .unit = "flags" },
{ "vfp", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFP }, .unit = "flags" },
+ { "vfp_vm", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFP_VM }, .unit = "flags" },
{ "vfpv3", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFPV3 }, .unit = "flags" },
{ "neon", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_NEON }, .unit = "flags" },
#elif ARCH_AARCH64
@@ -204,6 +205,7 @@ static const struct {
{ AV_CPU_FLAG_ARMV6, "armv6" },
{ AV_CPU_FLAG_ARMV6T2, "armv6t2" },
{ AV_CPU_FLAG_VFP, "vfp" },
+ { AV_CPU_FLAG_VFP_VM, "vfp_vm" },
{ AV_CPU_FLAG_VFPV3, "vfpv3" },
{ AV_CPU_FLAG_NEON, "neon" },
#elif ARCH_PPC
diff --git a/libavutil/cpu.h b/libavutil/cpu.h
index 9c77ce6e47..d640e79783 100644
--- a/libavutil/cpu.h
+++ b/libavutil/cpu.h
@@ -62,6 +62,7 @@
#define AV_CPU_FLAG_VFPV3 (1 << 4)
#define AV_CPU_FLAG_NEON (1 << 5)
#define AV_CPU_FLAG_ARMV8 (1 << 6)
+#define AV_CPU_FLAG_VFP_VM (1 << 7) ///< VFPv2 vector mode, deprecated in ARMv7-A and unavailable in various CPUs implementations
/**
* Return the flags which specify extensions supported by the CPU.
diff --git a/libavutil/version.h b/libavutil/version.h
index 7131122590..802a44549f 100644
--- a/libavutil/version.h
+++ b/libavutil/version.h
@@ -54,7 +54,7 @@
*/
#define LIBAVUTIL_VERSION_MAJOR 55
-#define LIBAVUTIL_VERSION_MINOR 3
+#define LIBAVUTIL_VERSION_MINOR 4
#define LIBAVUTIL_VERSION_MICRO 0
#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
diff --git a/tests/checkasm/checkasm.c b/tests/checkasm/checkasm.c
index 70627717a4..37bc13983d 100644
--- a/tests/checkasm/checkasm.c
+++ b/tests/checkasm/checkasm.c
@@ -89,6 +89,7 @@ static const struct {
{ "ARMV6", "armv6", AV_CPU_FLAG_ARMV6 },
{ "ARMV6T2", "armv6t2", AV_CPU_FLAG_ARMV6T2 },
{ "VFP", "vfp", AV_CPU_FLAG_VFP },
+ { "VFP_VM", "vfp_vm", AV_CPU_FLAG_VFP_VM },
{ "VFPV3", "vfp3", AV_CPU_FLAG_VFPV3 },
{ "NEON", "neon", AV_CPU_FLAG_NEON },
#elif ARCH_PPC