]> git.sesse.net Git - ffmpeg/commitdiff
arm: add a cpu flag for the VFPv2 vector mode
authorJanne Grunau <janne-libav@jannau.net>
Wed, 9 Dec 2015 21:28:36 +0000 (22:28 +0100)
committerJanne Grunau <janne-libav@jannau.net>
Mon, 14 Dec 2015 15:42:35 +0000 (16:42 +0100)
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.

libavcodec/arm/dcadsp_init_arm.c
libavcodec/arm/fft_init_arm.c
libavcodec/arm/fmtconvert_init_arm.c
libavutil/arm/cpu.c
libavutil/arm/cpu.h
libavutil/cpu.c
libavutil/cpu.h
libavutil/version.h
tests/checkasm/checkasm.c

index 540048415f7f4b5759c5bef0004eed90f937c7bf..252f4aeadd9b8e0b765f8f2b8cf30dce7b6ef175 100644 (file)
@@ -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;
index bc143c10fb2a8039881ae1b5a8617ce2bf451112..6d6fa220a5237286ae919008f2d225afb201de08 100644 (file)
@@ -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;
index 27d3c88011f4d668fe7d6bb433a4d2f4e247e1e6..6a80bfb6b3a987d8a9b889715c4a3f39d907c261 100644 (file)
@@ -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;
index 8bdaa884696b9fbf4fd8221542b8be0baadf5c7b..2effb726105530f5718e4dfd1e7b69d8904fa559 100644 (file)
@@ -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;
 }
 
index 224409afeeb426f9ad73862b447f631879512f68..5563fc1c690269dcb8c3cb8b8248bb6759e0082c 100644 (file)
 #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. */
index e24b9dd6796a8534af149395a012b45bd61f8d47..5f04461f6b4be6bd80fe1269175f97aa0496e3e2 100644 (file)
@@ -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
index 9c77ce6e471edab311185dc504658d6143a07078..d640e79783e948f0dc77802be55a20e670961efa 100644 (file)
@@ -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.
index 71311225908cd552c70b2cc676e2cfbda82669f4..802a44549f6617da951bb1799d4ad87e53270d7b 100644 (file)
@@ -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, \
index 70627717a499ef7bdff29ae831b13b1dd1f40880..37bc13983d4367eed908b07c0b43f6a13ae958c0 100644 (file)
@@ -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