diff options
Diffstat (limited to 'lib/rbcodec/codecs/libopus/celt/x86/x86cpu.c')
-rw-r--r-- | lib/rbcodec/codecs/libopus/celt/x86/x86cpu.c | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libopus/celt/x86/x86cpu.c b/lib/rbcodec/codecs/libopus/celt/x86/x86cpu.c new file mode 100644 index 0000000000..080eb25e41 --- /dev/null +++ b/lib/rbcodec/codecs/libopus/celt/x86/x86cpu.c | |||
@@ -0,0 +1,157 @@ | |||
1 | /* Copyright (c) 2014, Cisco Systems, INC | ||
2 | Written by XiangMingZhu WeiZhou MinPeng YanWang | ||
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 | #ifdef HAVE_CONFIG_H | ||
29 | #include "config.h" | ||
30 | #endif | ||
31 | |||
32 | #include "cpu_support.h" | ||
33 | #include "macros.h" | ||
34 | #include "main.h" | ||
35 | #include "pitch.h" | ||
36 | #include "x86cpu.h" | ||
37 | |||
38 | #if (defined(OPUS_X86_MAY_HAVE_SSE) && !defined(OPUS_X86_PRESUME_SSE)) || \ | ||
39 | (defined(OPUS_X86_MAY_HAVE_SSE2) && !defined(OPUS_X86_PRESUME_SSE2)) || \ | ||
40 | (defined(OPUS_X86_MAY_HAVE_SSE4_1) && !defined(OPUS_X86_PRESUME_SSE4_1)) || \ | ||
41 | (defined(OPUS_X86_MAY_HAVE_AVX) && !defined(OPUS_X86_PRESUME_AVX)) | ||
42 | |||
43 | |||
44 | #if defined(_MSC_VER) | ||
45 | |||
46 | #include <intrin.h> | ||
47 | static _inline void cpuid(unsigned int CPUInfo[4], unsigned int InfoType) | ||
48 | { | ||
49 | __cpuid((int*)CPUInfo, InfoType); | ||
50 | } | ||
51 | |||
52 | #else | ||
53 | |||
54 | #if defined(CPU_INFO_BY_C) | ||
55 | #include <cpuid.h> | ||
56 | #endif | ||
57 | |||
58 | static void cpuid(unsigned int CPUInfo[4], unsigned int InfoType) | ||
59 | { | ||
60 | #if defined(CPU_INFO_BY_ASM) | ||
61 | #if defined(__i386__) && defined(__PIC__) | ||
62 | /* %ebx is PIC register in 32-bit, so mustn't clobber it. */ | ||
63 | __asm__ __volatile__ ( | ||
64 | "xchg %%ebx, %1\n" | ||
65 | "cpuid\n" | ||
66 | "xchg %%ebx, %1\n": | ||
67 | "=a" (CPUInfo[0]), | ||
68 | "=r" (CPUInfo[1]), | ||
69 | "=c" (CPUInfo[2]), | ||
70 | "=d" (CPUInfo[3]) : | ||
71 | "0" (InfoType) | ||
72 | ); | ||
73 | #else | ||
74 | __asm__ __volatile__ ( | ||
75 | "cpuid": | ||
76 | "=a" (CPUInfo[0]), | ||
77 | "=b" (CPUInfo[1]), | ||
78 | "=c" (CPUInfo[2]), | ||
79 | "=d" (CPUInfo[3]) : | ||
80 | "0" (InfoType) | ||
81 | ); | ||
82 | #endif | ||
83 | #elif defined(CPU_INFO_BY_C) | ||
84 | __get_cpuid(InfoType, &(CPUInfo[0]), &(CPUInfo[1]), &(CPUInfo[2]), &(CPUInfo[3])); | ||
85 | #endif | ||
86 | } | ||
87 | |||
88 | #endif | ||
89 | |||
90 | typedef struct CPU_Feature{ | ||
91 | /* SIMD: 128-bit */ | ||
92 | int HW_SSE; | ||
93 | int HW_SSE2; | ||
94 | int HW_SSE41; | ||
95 | /* SIMD: 256-bit */ | ||
96 | int HW_AVX; | ||
97 | } CPU_Feature; | ||
98 | |||
99 | static void opus_cpu_feature_check(CPU_Feature *cpu_feature) | ||
100 | { | ||
101 | unsigned int info[4] = {0}; | ||
102 | unsigned int nIds = 0; | ||
103 | |||
104 | cpuid(info, 0); | ||
105 | nIds = info[0]; | ||
106 | |||
107 | if (nIds >= 1){ | ||
108 | cpuid(info, 1); | ||
109 | cpu_feature->HW_SSE = (info[3] & (1 << 25)) != 0; | ||
110 | cpu_feature->HW_SSE2 = (info[3] & (1 << 26)) != 0; | ||
111 | cpu_feature->HW_SSE41 = (info[2] & (1 << 19)) != 0; | ||
112 | cpu_feature->HW_AVX = (info[2] & (1 << 28)) != 0; | ||
113 | } | ||
114 | else { | ||
115 | cpu_feature->HW_SSE = 0; | ||
116 | cpu_feature->HW_SSE2 = 0; | ||
117 | cpu_feature->HW_SSE41 = 0; | ||
118 | cpu_feature->HW_AVX = 0; | ||
119 | } | ||
120 | } | ||
121 | |||
122 | int opus_select_arch(void) | ||
123 | { | ||
124 | CPU_Feature cpu_feature; | ||
125 | int arch; | ||
126 | |||
127 | opus_cpu_feature_check(&cpu_feature); | ||
128 | |||
129 | arch = 0; | ||
130 | if (!cpu_feature.HW_SSE) | ||
131 | { | ||
132 | return arch; | ||
133 | } | ||
134 | arch++; | ||
135 | |||
136 | if (!cpu_feature.HW_SSE2) | ||
137 | { | ||
138 | return arch; | ||
139 | } | ||
140 | arch++; | ||
141 | |||
142 | if (!cpu_feature.HW_SSE41) | ||
143 | { | ||
144 | return arch; | ||
145 | } | ||
146 | arch++; | ||
147 | |||
148 | if (!cpu_feature.HW_AVX) | ||
149 | { | ||
150 | return arch; | ||
151 | } | ||
152 | arch++; | ||
153 | |||
154 | return arch; | ||
155 | } | ||
156 | |||
157 | #endif | ||