1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/media/libopus/celt/arm/armcpu.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,174 @@ 1.4 +/* Copyright (c) 2010 Xiph.Org Foundation 1.5 + * Copyright (c) 2013 Parrot */ 1.6 +/* 1.7 + Redistribution and use in source and binary forms, with or without 1.8 + modification, are permitted provided that the following conditions 1.9 + are met: 1.10 + 1.11 + - Redistributions of source code must retain the above copyright 1.12 + notice, this list of conditions and the following disclaimer. 1.13 + 1.14 + - Redistributions in binary form must reproduce the above copyright 1.15 + notice, this list of conditions and the following disclaimer in the 1.16 + documentation and/or other materials provided with the distribution. 1.17 + 1.18 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1.19 + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1.20 + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1.21 + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 1.22 + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 1.23 + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 1.24 + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 1.25 + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 1.26 + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 1.27 + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 1.28 + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1.29 +*/ 1.30 + 1.31 +/* Original code from libtheora modified to suit to Opus */ 1.32 + 1.33 +#ifdef HAVE_CONFIG_H 1.34 +#include "config.h" 1.35 +#endif 1.36 + 1.37 +#ifdef OPUS_HAVE_RTCD 1.38 + 1.39 +#include "armcpu.h" 1.40 +#include "cpu_support.h" 1.41 +#include "os_support.h" 1.42 +#include "opus_types.h" 1.43 + 1.44 +#define OPUS_CPU_ARM_V4 (1) 1.45 +#define OPUS_CPU_ARM_EDSP (1<<1) 1.46 +#define OPUS_CPU_ARM_MEDIA (1<<2) 1.47 +#define OPUS_CPU_ARM_NEON (1<<3) 1.48 + 1.49 +#if defined(_MSC_VER) 1.50 +/*For GetExceptionCode() and EXCEPTION_ILLEGAL_INSTRUCTION.*/ 1.51 +# define WIN32_LEAN_AND_MEAN 1.52 +# define WIN32_EXTRA_LEAN 1.53 +# include <windows.h> 1.54 + 1.55 +static OPUS_INLINE opus_uint32 opus_cpu_capabilities(void){ 1.56 + opus_uint32 flags; 1.57 + flags=0; 1.58 + /* MSVC has no OPUS_INLINE __asm support for ARM, but it does let you __emit 1.59 + * instructions via their assembled hex code. 1.60 + * All of these instructions should be essentially nops. */ 1.61 +# if defined(OPUS_ARM_MAY_HAVE_EDSP) 1.62 + __try{ 1.63 + /*PLD [r13]*/ 1.64 + __emit(0xF5DDF000); 1.65 + flags|=OPUS_CPU_ARM_EDSP; 1.66 + } 1.67 + __except(GetExceptionCode()==EXCEPTION_ILLEGAL_INSTRUCTION){ 1.68 + /*Ignore exception.*/ 1.69 + } 1.70 +# if defined(OPUS_ARM_MAY_HAVE_MEDIA) 1.71 + __try{ 1.72 + /*SHADD8 r3,r3,r3*/ 1.73 + __emit(0xE6333F93); 1.74 + flags|=OPUS_CPU_ARM_MEDIA; 1.75 + } 1.76 + __except(GetExceptionCode()==EXCEPTION_ILLEGAL_INSTRUCTION){ 1.77 + /*Ignore exception.*/ 1.78 + } 1.79 +# if defined(OPUS_ARM_MAY_HAVE_NEON) 1.80 + __try{ 1.81 + /*VORR q0,q0,q0*/ 1.82 + __emit(0xF2200150); 1.83 + flags|=OPUS_CPU_ARM_NEON; 1.84 + } 1.85 + __except(GetExceptionCode()==EXCEPTION_ILLEGAL_INSTRUCTION){ 1.86 + /*Ignore exception.*/ 1.87 + } 1.88 +# endif 1.89 +# endif 1.90 +# endif 1.91 + return flags; 1.92 +} 1.93 + 1.94 +#elif defined(__linux__) 1.95 +/* Linux based */ 1.96 +opus_uint32 opus_cpu_capabilities(void) 1.97 +{ 1.98 + opus_uint32 flags = 0; 1.99 + FILE *cpuinfo; 1.100 + 1.101 + /* Reading /proc/self/auxv would be easier, but that doesn't work reliably on 1.102 + * Android */ 1.103 + cpuinfo = fopen("/proc/cpuinfo", "r"); 1.104 + 1.105 + if(cpuinfo != NULL) 1.106 + { 1.107 + /* 512 should be enough for anybody (it's even enough for all the flags that 1.108 + * x86 has accumulated... so far). */ 1.109 + char buf[512]; 1.110 + 1.111 + while(fgets(buf, 512, cpuinfo) != NULL) 1.112 + { 1.113 +# if defined(OPUS_ARM_MAY_HAVE_EDSP) || defined(OPUS_ARM_MAY_HAVE_NEON) 1.114 + /* Search for edsp and neon flag */ 1.115 + if(memcmp(buf, "Features", 8) == 0) 1.116 + { 1.117 + char *p; 1.118 +# if defined(OPUS_ARM_MAY_HAVE_EDSP) 1.119 + p = strstr(buf, " edsp"); 1.120 + if(p != NULL && (p[5] == ' ' || p[5] == '\n')) 1.121 + flags |= OPUS_CPU_ARM_EDSP; 1.122 +# endif 1.123 + 1.124 +# if defined(OPUS_ARM_MAY_HAVE_NEON) 1.125 + p = strstr(buf, " neon"); 1.126 + if(p != NULL && (p[5] == ' ' || p[5] == '\n')) 1.127 + flags |= OPUS_CPU_ARM_NEON; 1.128 +# endif 1.129 + } 1.130 +# endif 1.131 + 1.132 +# if defined(OPUS_ARM_MAY_HAVE_MEDIA) 1.133 + /* Search for media capabilities (>= ARMv6) */ 1.134 + if(memcmp(buf, "CPU architecture:", 17) == 0) 1.135 + { 1.136 + int version; 1.137 + version = atoi(buf+17); 1.138 + 1.139 + if(version >= 6) 1.140 + flags |= OPUS_CPU_ARM_MEDIA; 1.141 + } 1.142 +# endif 1.143 + } 1.144 + 1.145 + fclose(cpuinfo); 1.146 + } 1.147 + return flags; 1.148 +} 1.149 +#else 1.150 +/* The feature registers which can tell us what the processor supports are 1.151 + * accessible in priveleged modes only, so we can't have a general user-space 1.152 + * detection method like on x86.*/ 1.153 +# error "Configured to use ARM asm but no CPU detection method available for " \ 1.154 + "your platform. Reconfigure with --disable-rtcd (or send patches)." 1.155 +#endif 1.156 + 1.157 +int opus_select_arch(void) 1.158 +{ 1.159 + opus_uint32 flags = opus_cpu_capabilities(); 1.160 + int arch = 0; 1.161 + 1.162 + if(!(flags & OPUS_CPU_ARM_EDSP)) 1.163 + return arch; 1.164 + arch++; 1.165 + 1.166 + if(!(flags & OPUS_CPU_ARM_MEDIA)) 1.167 + return arch; 1.168 + arch++; 1.169 + 1.170 + if(!(flags & OPUS_CPU_ARM_NEON)) 1.171 + return arch; 1.172 + arch++; 1.173 + 1.174 + return arch; 1.175 +} 1.176 + 1.177 +#endif