diff options
author | William Wilgus <me.theuser@yahoo.com> | 2019-01-04 02:01:18 -0600 |
---|---|---|
committer | Solomon Peachy <pizza@shaftnet.org> | 2021-04-23 14:23:04 +0000 |
commit | 14c6bb798d6bebc80f07e863236adbaf8d156a9c (patch) | |
tree | 551a4b641906c2626af844fa3239c1b2b1ff0ad3 /lib/rbcodec/codecs/libopus/celt/arm/armcpu.c | |
parent | 75d93937965ec4df70d37df6d4feea04577c996b (diff) | |
download | rockbox-14c6bb798d6bebc80f07e863236adbaf8d156a9c.tar.gz rockbox-14c6bb798d6bebc80f07e863236adbaf8d156a9c.zip |
Sync opus codec to upstream git
Change-Id: I0cfcc0005c4ad7bfbb1aaf454188ce70fb043dc1
Diffstat (limited to 'lib/rbcodec/codecs/libopus/celt/arm/armcpu.c')
-rw-r--r-- | lib/rbcodec/codecs/libopus/celt/arm/armcpu.c | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libopus/celt/arm/armcpu.c b/lib/rbcodec/codecs/libopus/celt/arm/armcpu.c new file mode 100644 index 0000000000..694a63b78e --- /dev/null +++ b/lib/rbcodec/codecs/libopus/celt/arm/armcpu.c | |||
@@ -0,0 +1,185 @@ | |||
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 | ||