19
19
#include "libavutil/cpu.h"
20
20
#include "config.h"
22
#define CORE_FLAG(f) \
23
(AV_CPU_FLAG_ ## f * (HAVE_ ## f ## _EXTERNAL || HAVE_ ## f ## _INLINE))
25
#define CORE_CPU_FLAGS \
26
(CORE_FLAG(ARMV5TE) | \
28
CORE_FLAG(ARMV6T2) | \
33
#if defined __linux__ || defined __ANDROID__
40
/* Relevant HWCAP values from kernel headers */
41
#define HWCAP_VFP (1 << 6)
42
#define HWCAP_EDSP (1 << 7)
43
#define HWCAP_THUMBEE (1 << 11)
44
#define HWCAP_NEON (1 << 12)
45
#define HWCAP_VFPv3 (1 << 13)
46
#define HWCAP_TLS (1 << 15)
48
static int get_hwcap(uint32_t *hwcap)
50
struct { uint32_t a_type; uint32_t a_val; } auxv;
51
FILE *f = fopen("/proc/self/auxv", "r");
57
while (fread(&auxv, sizeof(auxv), 1, f) > 0) {
58
if (auxv.a_type == AT_HWCAP) {
69
int ff_get_cpu_flags_arm(void)
71
int flags = CORE_CPU_FLAGS;
74
if (get_hwcap(&hwcap) < 0)
77
#define check_cap(cap, flag) do { \
78
if (hwcap & HWCAP_ ## cap) \
79
flags |= AV_CPU_FLAG_ ## flag; \
82
/* No flags explicitly indicate v6 or v6T2 so check others which
84
check_cap(EDSP, ARMV5TE);
85
check_cap(TLS, ARMV6);
86
check_cap(THUMBEE, ARMV6T2);
88
check_cap(VFPv3, VFPV3);
89
check_cap(NEON, NEON);
91
/* The v6 checks above are not reliable so let higher flags
93
if (flags & (AV_CPU_FLAG_VFPV3 | AV_CPU_FLAG_NEON))
94
flags |= AV_CPU_FLAG_ARMV6T2;
95
if (flags & AV_CPU_FLAG_ARMV6T2)
96
flags |= AV_CPU_FLAG_ARMV6;
22
103
int ff_get_cpu_flags_arm(void)
24
105
return AV_CPU_FLAG_ARMV5TE * HAVE_ARMV5TE |
25
106
AV_CPU_FLAG_ARMV6 * HAVE_ARMV6 |
26
107
AV_CPU_FLAG_ARMV6T2 * HAVE_ARMV6T2 |
27
AV_CPU_FLAG_VFP * HAVE_ARMVFP |
108
AV_CPU_FLAG_VFP * HAVE_VFP |
28
109
AV_CPU_FLAG_VFPV3 * HAVE_VFPV3 |
29
110
AV_CPU_FLAG_NEON * HAVE_NEON;