1e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org/* Copyright (c) 2010 Xiph.Org Foundation 2e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org * Copyright (c) 2013 Parrot */ 3e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org/* 4e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org Redistribution and use in source and binary forms, with or without 5e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org modification, are permitted provided that the following conditions 6e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org are met: 7e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 8e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org - Redistributions of source code must retain the above copyright 9e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org notice, this list of conditions and the following disclaimer. 10e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 11e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org - Redistributions in binary form must reproduce the above copyright 12e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org notice, this list of conditions and the following disclaimer in the 13e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org documentation and/or other materials provided with the distribution. 14e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 15e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 19e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 20e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 22e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 23e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 24e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org*/ 27e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 28e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org/* Original code from libtheora modified to suit to Opus */ 29e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 30e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#ifdef HAVE_CONFIG_H 31e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#include "config.h" 32e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#endif 33e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 34e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#ifdef OPUS_HAVE_RTCD 35e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 36e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#include "armcpu.h" 37e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#include "cpu_support.h" 38e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#include "os_support.h" 39e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#include "opus_types.h" 40e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 41e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#define OPUS_CPU_ARM_V4 (1) 42e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#define OPUS_CPU_ARM_EDSP (1<<1) 43e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#define OPUS_CPU_ARM_MEDIA (1<<2) 44e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#define OPUS_CPU_ARM_NEON (1<<3) 45e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 46e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#if defined(_MSC_VER) 47e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org/*For GetExceptionCode() and EXCEPTION_ILLEGAL_INSTRUCTION.*/ 48e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org# define WIN32_LEAN_AND_MEAN 49e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org# define WIN32_EXTRA_LEAN 50e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org# include <windows.h> 51e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 523c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.comstatic OPUS_INLINE opus_uint32 opus_cpu_capabilities(void){ 53e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_uint32 flags; 54e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org flags=0; 553c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com /* MSVC has no OPUS_INLINE __asm support for ARM, but it does let you __emit 56e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org * instructions via their assembled hex code. 57e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org * All of these instructions should be essentially nops. */ 583c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com# if defined(OPUS_ARM_MAY_HAVE_EDSP) 59e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org __try{ 60e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /*PLD [r13]*/ 61e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org __emit(0xF5DDF000); 62e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org flags|=OPUS_CPU_ARM_EDSP; 63e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 64e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org __except(GetExceptionCode()==EXCEPTION_ILLEGAL_INSTRUCTION){ 65e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /*Ignore exception.*/ 66e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 673c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com# if defined(OPUS_ARM_MAY_HAVE_MEDIA) 68e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org __try{ 69e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /*SHADD8 r3,r3,r3*/ 70e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org __emit(0xE6333F93); 71e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org flags|=OPUS_CPU_ARM_MEDIA; 72e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 73e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org __except(GetExceptionCode()==EXCEPTION_ILLEGAL_INSTRUCTION){ 74e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /*Ignore exception.*/ 75e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 763c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com# if defined(OPUS_ARM_MAY_HAVE_NEON) 77e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org __try{ 78e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /*VORR q0,q0,q0*/ 79e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org __emit(0xF2200150); 80e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org flags|=OPUS_CPU_ARM_NEON; 81e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 82e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org __except(GetExceptionCode()==EXCEPTION_ILLEGAL_INSTRUCTION){ 83e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /*Ignore exception.*/ 84e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 85e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org# endif 86e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org# endif 87e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org# endif 88e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return flags; 89e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org} 90e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 91e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#elif defined(__linux__) 92e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org/* Linux based */ 93e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgopus_uint32 opus_cpu_capabilities(void) 94e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org{ 95e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_uint32 flags = 0; 96e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org FILE *cpuinfo; 97e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 98e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* Reading /proc/self/auxv would be easier, but that doesn't work reliably on 99e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org * Android */ 100e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org cpuinfo = fopen("/proc/cpuinfo", "r"); 101e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 102e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if(cpuinfo != NULL) 103e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 104e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* 512 should be enough for anybody (it's even enough for all the flags that 105e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org * x86 has accumulated... so far). */ 106e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org char buf[512]; 107e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 108e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org while(fgets(buf, 512, cpuinfo) != NULL) 109e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 1103c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com# if defined(OPUS_ARM_MAY_HAVE_EDSP) || defined(OPUS_ARM_MAY_HAVE_NEON) 111e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* Search for edsp and neon flag */ 112e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if(memcmp(buf, "Features", 8) == 0) 113e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 114e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org char *p; 1153c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com# if defined(OPUS_ARM_MAY_HAVE_EDSP) 116e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org p = strstr(buf, " edsp"); 117e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if(p != NULL && (p[5] == ' ' || p[5] == '\n')) 118e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org flags |= OPUS_CPU_ARM_EDSP; 1193c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com# endif 120e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 1213c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com# if defined(OPUS_ARM_MAY_HAVE_NEON) 122e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org p = strstr(buf, " neon"); 123e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if(p != NULL && (p[5] == ' ' || p[5] == '\n')) 124e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org flags |= OPUS_CPU_ARM_NEON; 1253c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com# endif 126e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 1273c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com# endif 128e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 1293c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com# if defined(OPUS_ARM_MAY_HAVE_MEDIA) 130e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* Search for media capabilities (>= ARMv6) */ 131e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if(memcmp(buf, "CPU architecture:", 17) == 0) 132e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 133e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int version; 134e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org version = atoi(buf+17); 135e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 136e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if(version >= 6) 137e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org flags |= OPUS_CPU_ARM_MEDIA; 138e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 1393c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com# endif 140e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 141e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 142e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org fclose(cpuinfo); 143e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 144e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return flags; 145e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org} 146e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#else 147e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org/* The feature registers which can tell us what the processor supports are 148e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org * accessible in priveleged modes only, so we can't have a general user-space 149e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org * detection method like on x86.*/ 150e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org# error "Configured to use ARM asm but no CPU detection method available for " \ 151e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org "your platform. Reconfigure with --disable-rtcd (or send patches)." 152e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#endif 153e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 154e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgint opus_select_arch(void) 155e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org{ 156e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_uint32 flags = opus_cpu_capabilities(); 157e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int arch = 0; 158e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 159e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if(!(flags & OPUS_CPU_ARM_EDSP)) 160e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return arch; 161e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org arch++; 162e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 163e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if(!(flags & OPUS_CPU_ARM_MEDIA)) 164e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return arch; 165e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org arch++; 166e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 167e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if(!(flags & OPUS_CPU_ARM_NEON)) 168e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return arch; 169e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org arch++; 170e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 171e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return arch; 172e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org} 173e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 174e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#endif 175