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