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