annotate src/opus-1.3/celt/arm/armcpu.c @ 168:ceec0dd9ec9c

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