Line data Source code
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 0 : 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 0 : }
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 0 : static void opus_cpu_feature_check(CPU_Feature *cpu_feature)
100 : {
101 0 : unsigned int info[4] = {0};
102 0 : unsigned int nIds = 0;
103 :
104 0 : cpuid(info, 0);
105 0 : nIds = info[0];
106 :
107 0 : if (nIds >= 1){
108 0 : cpuid(info, 1);
109 0 : cpu_feature->HW_SSE = (info[3] & (1 << 25)) != 0;
110 0 : cpu_feature->HW_SSE2 = (info[3] & (1 << 26)) != 0;
111 0 : cpu_feature->HW_SSE41 = (info[2] & (1 << 19)) != 0;
112 0 : cpu_feature->HW_AVX = (info[2] & (1 << 28)) != 0;
113 : }
114 : else {
115 0 : cpu_feature->HW_SSE = 0;
116 0 : cpu_feature->HW_SSE2 = 0;
117 0 : cpu_feature->HW_SSE41 = 0;
118 0 : cpu_feature->HW_AVX = 0;
119 : }
120 0 : }
121 :
122 0 : int opus_select_arch(void)
123 : {
124 : CPU_Feature cpu_feature;
125 : int arch;
126 :
127 0 : opus_cpu_feature_check(&cpu_feature);
128 :
129 0 : arch = 0;
130 0 : if (!cpu_feature.HW_SSE)
131 : {
132 0 : return arch;
133 : }
134 0 : arch++;
135 :
136 0 : if (!cpu_feature.HW_SSE2)
137 : {
138 0 : return arch;
139 : }
140 0 : arch++;
141 :
142 0 : if (!cpu_feature.HW_SSE41)
143 : {
144 0 : return arch;
145 : }
146 0 : arch++;
147 :
148 0 : if (!cpu_feature.HW_AVX)
149 : {
150 0 : return arch;
151 : }
152 0 : arch++;
153 :
154 0 : return arch;
155 : }
156 :
157 : #endif
|