~ubuntu-branches/ubuntu/utopic/libav/utopic

« back to all changes in this revision

Viewing changes to libavutil/arm/cpu.c

  • Committer: Package Import Robot
  • Author(s): Reinhard Tartler
  • Date: 2012-12-21 15:32:13 UTC
  • mto: (1.2.18)
  • mto: This revision was merged to the branch mainline in revision 34.
  • Revision ID: package-import@ubuntu.com-20121221153213-fudzrugjzivtv0wp
Tags: upstream-9~beta3
ImportĀ upstreamĀ versionĀ 9~beta3

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
#include "libavutil/cpu.h"
20
20
#include "config.h"
21
21
 
 
22
#define CORE_FLAG(f) \
 
23
    (AV_CPU_FLAG_ ## f * (HAVE_ ## f ## _EXTERNAL || HAVE_ ## f ## _INLINE))
 
24
 
 
25
#define CORE_CPU_FLAGS                          \
 
26
    (CORE_FLAG(ARMV5TE) |                       \
 
27
     CORE_FLAG(ARMV6)   |                       \
 
28
     CORE_FLAG(ARMV6T2) |                       \
 
29
     CORE_FLAG(VFP)     |                       \
 
30
     CORE_FLAG(VFPV3)   |                       \
 
31
     CORE_FLAG(NEON))
 
32
 
 
33
#if defined __linux__ || defined __ANDROID__
 
34
 
 
35
#include <stdint.h>
 
36
#include <stdio.h>
 
37
 
 
38
#define AT_HWCAP        16
 
39
 
 
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)
 
47
 
 
48
static int get_hwcap(uint32_t *hwcap)
 
49
{
 
50
    struct { uint32_t a_type; uint32_t a_val; } auxv;
 
51
    FILE *f = fopen("/proc/self/auxv", "r");
 
52
    int err = -1;
 
53
 
 
54
    if (!f)
 
55
        return -1;
 
56
 
 
57
    while (fread(&auxv, sizeof(auxv), 1, f) > 0) {
 
58
        if (auxv.a_type == AT_HWCAP) {
 
59
            *hwcap = auxv.a_val;
 
60
            err = 0;
 
61
            break;
 
62
        }
 
63
    }
 
64
 
 
65
    fclose(f);
 
66
    return err;
 
67
}
 
68
 
 
69
int ff_get_cpu_flags_arm(void)
 
70
{
 
71
    int flags = CORE_CPU_FLAGS;
 
72
    uint32_t hwcap;
 
73
 
 
74
    if (get_hwcap(&hwcap) < 0)
 
75
        return flags;
 
76
 
 
77
#define check_cap(cap, flag) do {               \
 
78
        if (hwcap & HWCAP_ ## cap)              \
 
79
            flags |= AV_CPU_FLAG_ ## flag;      \
 
80
    } while (0)
 
81
 
 
82
    /* No flags explicitly indicate v6 or v6T2 so check others which
 
83
       imply support. */
 
84
    check_cap(EDSP,    ARMV5TE);
 
85
    check_cap(TLS,     ARMV6);
 
86
    check_cap(THUMBEE, ARMV6T2);
 
87
    check_cap(VFP,     VFP);
 
88
    check_cap(VFPv3,   VFPV3);
 
89
    check_cap(NEON,    NEON);
 
90
 
 
91
    /* The v6 checks above are not reliable so let higher flags
 
92
       trickle down. */
 
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;
 
97
 
 
98
    return flags;
 
99
}
 
100
 
 
101
#else
 
102
 
22
103
int ff_get_cpu_flags_arm(void)
23
104
{
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;
30
111
}
 
112
 
 
113
#endif