media/libvpx/vpx_ports/arm_cpudetect.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /*
michael@0 2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
michael@0 3 *
michael@0 4 * Use of this source code is governed by a BSD-style license
michael@0 5 * that can be found in the LICENSE file in the root of the source
michael@0 6 * tree. An additional intellectual property rights grant can be found
michael@0 7 * in the file PATENTS. All contributing project authors may
michael@0 8 * be found in the AUTHORS file in the root of the source tree.
michael@0 9 */
michael@0 10
michael@0 11 #include <stdlib.h>
michael@0 12 #include <string.h>
michael@0 13 #include "arm.h"
michael@0 14
michael@0 15 static int arm_cpu_env_flags(int *flags) {
michael@0 16 char *env;
michael@0 17 env = getenv("VPX_SIMD_CAPS");
michael@0 18 if (env && *env) {
michael@0 19 *flags = (int)strtol(env, NULL, 0);
michael@0 20 return 0;
michael@0 21 }
michael@0 22 *flags = 0;
michael@0 23 return -1;
michael@0 24 }
michael@0 25
michael@0 26 static int arm_cpu_env_mask(void) {
michael@0 27 char *env;
michael@0 28 env = getenv("VPX_SIMD_CAPS_MASK");
michael@0 29 return env && *env ? (int)strtol(env, NULL, 0) : ~0;
michael@0 30 }
michael@0 31
michael@0 32 #if !CONFIG_RUNTIME_CPU_DETECT
michael@0 33
michael@0 34 int arm_cpu_caps(void) {
michael@0 35 /* This function should actually be a no-op. There is no way to adjust any of
michael@0 36 * these because the RTCD tables do not exist: the functions are called
michael@0 37 * statically */
michael@0 38 int flags;
michael@0 39 int mask;
michael@0 40 if (!arm_cpu_env_flags(&flags)) {
michael@0 41 return flags;
michael@0 42 }
michael@0 43 mask = arm_cpu_env_mask();
michael@0 44 #if HAVE_EDSP
michael@0 45 flags |= HAS_EDSP;
michael@0 46 #endif /* HAVE_EDSP */
michael@0 47 #if HAVE_MEDIA
michael@0 48 flags |= HAS_MEDIA;
michael@0 49 #endif /* HAVE_MEDIA */
michael@0 50 #if HAVE_NEON
michael@0 51 flags |= HAS_NEON;
michael@0 52 #endif /* HAVE_NEON */
michael@0 53 return flags & mask;
michael@0 54 }
michael@0 55
michael@0 56 #elif defined(_MSC_VER) /* end !CONFIG_RUNTIME_CPU_DETECT */
michael@0 57 /*For GetExceptionCode() and EXCEPTION_ILLEGAL_INSTRUCTION.*/
michael@0 58 #define WIN32_LEAN_AND_MEAN
michael@0 59 #define WIN32_EXTRA_LEAN
michael@0 60 #include <windows.h>
michael@0 61
michael@0 62 int arm_cpu_caps(void) {
michael@0 63 int flags;
michael@0 64 int mask;
michael@0 65 if (!arm_cpu_env_flags(&flags)) {
michael@0 66 return flags;
michael@0 67 }
michael@0 68 mask = arm_cpu_env_mask();
michael@0 69 /* MSVC has no inline __asm support for ARM, but it does let you __emit
michael@0 70 * instructions via their assembled hex code.
michael@0 71 * All of these instructions should be essentially nops.
michael@0 72 */
michael@0 73 #if HAVE_EDSP
michael@0 74 if (mask & HAS_EDSP) {
michael@0 75 __try {
michael@0 76 /*PLD [r13]*/
michael@0 77 __emit(0xF5DDF000);
michael@0 78 flags |= HAS_EDSP;
michael@0 79 } __except (GetExceptionCode() == EXCEPTION_ILLEGAL_INSTRUCTION) {
michael@0 80 /*Ignore exception.*/
michael@0 81 }
michael@0 82 }
michael@0 83 #if HAVE_MEDIA
michael@0 84 if (mask & HAS_MEDIA)
michael@0 85 __try {
michael@0 86 /*SHADD8 r3,r3,r3*/
michael@0 87 __emit(0xE6333F93);
michael@0 88 flags |= HAS_MEDIA;
michael@0 89 } __except (GetExceptionCode() == EXCEPTION_ILLEGAL_INSTRUCTION) {
michael@0 90 /*Ignore exception.*/
michael@0 91 }
michael@0 92 }
michael@0 93 #if HAVE_NEON
michael@0 94 if (mask &HAS_NEON) {
michael@0 95 __try {
michael@0 96 /*VORR q0,q0,q0*/
michael@0 97 __emit(0xF2200150);
michael@0 98 flags |= HAS_NEON;
michael@0 99 } __except (GetExceptionCode() == EXCEPTION_ILLEGAL_INSTRUCTION) {
michael@0 100 /*Ignore exception.*/
michael@0 101 }
michael@0 102 }
michael@0 103 #endif /* HAVE_NEON */
michael@0 104 #endif /* HAVE_MEDIA */
michael@0 105 #endif /* HAVE_EDSP */
michael@0 106 return flags & mask;
michael@0 107 }
michael@0 108
michael@0 109 #elif defined(__ANDROID__) /* end _MSC_VER */
michael@0 110 #include <cpu-features.h>
michael@0 111
michael@0 112 int arm_cpu_caps(void) {
michael@0 113 int flags;
michael@0 114 int mask;
michael@0 115 uint64_t features;
michael@0 116 if (!arm_cpu_env_flags(&flags)) {
michael@0 117 return flags;
michael@0 118 }
michael@0 119 mask = arm_cpu_env_mask();
michael@0 120 features = android_getCpuFeatures();
michael@0 121
michael@0 122 #if HAVE_EDSP
michael@0 123 flags |= HAS_EDSP;
michael@0 124 #endif /* HAVE_EDSP */
michael@0 125 #if HAVE_MEDIA
michael@0 126 flags |= HAS_MEDIA;
michael@0 127 #endif /* HAVE_MEDIA */
michael@0 128 #if HAVE_NEON
michael@0 129 if (features & ANDROID_CPU_ARM_FEATURE_NEON)
michael@0 130 flags |= HAS_NEON;
michael@0 131 #endif /* HAVE_NEON */
michael@0 132 return flags & mask;
michael@0 133 }
michael@0 134
michael@0 135 #elif defined(__linux__) /* end __ANDROID__ */
michael@0 136
michael@0 137 #include <stdio.h>
michael@0 138
michael@0 139 int arm_cpu_caps(void) {
michael@0 140 FILE *fin;
michael@0 141 int flags;
michael@0 142 int mask;
michael@0 143 if (!arm_cpu_env_flags(&flags)) {
michael@0 144 return flags;
michael@0 145 }
michael@0 146 mask = arm_cpu_env_mask();
michael@0 147 /* Reading /proc/self/auxv would be easier, but that doesn't work reliably
michael@0 148 * on Android.
michael@0 149 * This also means that detection will fail in Scratchbox.
michael@0 150 */
michael@0 151 fin = fopen("/proc/cpuinfo", "r");
michael@0 152 if (fin != NULL) {
michael@0 153 /* 512 should be enough for anybody (it's even enough for all the flags
michael@0 154 * that x86 has accumulated... so far).
michael@0 155 */
michael@0 156 char buf[512];
michael@0 157 while (fgets(buf, 511, fin) != NULL) {
michael@0 158 #if HAVE_EDSP || HAVE_NEON
michael@0 159 if (memcmp(buf, "Features", 8) == 0) {
michael@0 160 char *p;
michael@0 161 #if HAVE_EDSP
michael@0 162 p = strstr(buf, " edsp");
michael@0 163 if (p != NULL && (p[5] == ' ' || p[5] == '\n')) {
michael@0 164 flags |= HAS_EDSP;
michael@0 165 }
michael@0 166 #if HAVE_NEON
michael@0 167 p = strstr(buf, " neon");
michael@0 168 if (p != NULL && (p[5] == ' ' || p[5] == '\n')) {
michael@0 169 flags |= HAS_NEON;
michael@0 170 }
michael@0 171 #endif /* HAVE_NEON */
michael@0 172 #endif /* HAVE_EDSP */
michael@0 173 }
michael@0 174 #endif /* HAVE_EDSP || HAVE_NEON */
michael@0 175 #if HAVE_MEDIA
michael@0 176 if (memcmp(buf, "CPU architecture:", 17) == 0) {
michael@0 177 int version;
michael@0 178 version = atoi(buf + 17);
michael@0 179 if (version >= 6) {
michael@0 180 flags |= HAS_MEDIA;
michael@0 181 }
michael@0 182 }
michael@0 183 #endif /* HAVE_MEDIA */
michael@0 184 }
michael@0 185 fclose(fin);
michael@0 186 }
michael@0 187 return flags & mask;
michael@0 188 }
michael@0 189 #else /* end __linux__ */
michael@0 190 #error "--enable-runtime-cpu-detect selected, but no CPU detection method " \
michael@0 191 "available for your platform. Reconfigure with --disable-runtime-cpu-detect."
michael@0 192 #endif

mercurial