blob: 58ef009492395a3d061bd061d983f0ca3b87e816 [file] [log] [blame]
Nicolas Capensc07dc4b2018-08-06 14:20:45 -04001// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include "CPUID.hpp"
16
17#if defined(_WIN32)
18 #ifndef WIN32_LEAN_AND_MEAN
19 #define WIN32_LEAN_AND_MEAN
20 #endif
21 #include <windows.h>
22 #include <intrin.h>
23 #include <float.h>
24#else
25 #include <unistd.h>
26 #include <sched.h>
27 #include <sys/types.h>
28#endif
29
30namespace rr
31{
32 bool CPUID::MMX = detectMMX();
33 bool CPUID::CMOV = detectCMOV();
34 bool CPUID::SSE = detectSSE();
35 bool CPUID::SSE2 = detectSSE2();
36 bool CPUID::SSE3 = detectSSE3();
37 bool CPUID::SSSE3 = detectSSSE3();
38 bool CPUID::SSE4_1 = detectSSE4_1();
39
40 bool CPUID::enableMMX = true;
41 bool CPUID::enableCMOV = true;
42 bool CPUID::enableSSE = true;
43 bool CPUID::enableSSE2 = true;
44 bool CPUID::enableSSE3 = true;
45 bool CPUID::enableSSSE3 = true;
46 bool CPUID::enableSSE4_1 = true;
47
48 void CPUID::setEnableMMX(bool enable)
49 {
50 enableMMX = enable;
51
52 if(!enableMMX)
53 {
54 enableSSE = false;
55 enableSSE2 = false;
56 enableSSE3 = false;
57 enableSSSE3 = false;
58 enableSSE4_1 = false;
59 }
60 }
61
62 void CPUID::setEnableCMOV(bool enable)
63 {
64 enableCMOV = enable;
65
66 if(!CMOV)
67 {
68 enableSSE = false;
69 enableSSE2 = false;
70 enableSSE3 = false;
71 enableSSSE3 = false;
72 enableSSE4_1 = false;
73 }
74 }
75
76 void CPUID::setEnableSSE(bool enable)
77 {
78 enableSSE = enable;
79
80 if(enableSSE)
81 {
82 enableMMX = true;
83 enableCMOV = true;
84 }
85 else
86 {
87 enableSSE2 = false;
88 enableSSE3 = false;
89 enableSSSE3 = false;
90 enableSSE4_1 = false;
91 }
92 }
93
94 void CPUID::setEnableSSE2(bool enable)
95 {
96 enableSSE2 = enable;
97
98 if(enableSSE2)
99 {
100 enableMMX = true;
101 enableCMOV = true;
102 enableSSE = true;
103 }
104 else
105 {
106 enableSSE3 = false;
107 enableSSSE3 = false;
108 enableSSE4_1 = false;
109 }
110 }
111
112 void CPUID::setEnableSSE3(bool enable)
113 {
114 enableSSE3 = enable;
115
116 if(enableSSE3)
117 {
118 enableMMX = true;
119 enableCMOV = true;
120 enableSSE = true;
121 enableSSE2 = true;
122 }
123 else
124 {
125 enableSSSE3 = false;
126 enableSSE4_1 = false;
127 }
128 }
129
130 void CPUID::setEnableSSSE3(bool enable)
131 {
132 enableSSSE3 = enable;
133
134 if(enableSSSE3)
135 {
136 enableMMX = true;
137 enableCMOV = true;
138 enableSSE = true;
139 enableSSE2 = true;
140 enableSSE3 = true;
141 }
142 else
143 {
144 enableSSE4_1 = false;
145 }
146 }
147
148 void CPUID::setEnableSSE4_1(bool enable)
149 {
150 enableSSE4_1 = enable;
151
152 if(enableSSE4_1)
153 {
154 enableMMX = true;
155 enableCMOV = true;
156 enableSSE = true;
157 enableSSE2 = true;
158 enableSSE3 = true;
159 enableSSSE3 = true;
160 }
161 }
162
163 static void cpuid(int registers[4], int info)
164 {
165 #if defined(__i386__) || defined(__x86_64__)
166 #if defined(_WIN32)
167 __cpuid(registers, info);
168 #else
169 __asm volatile("cpuid": "=a" (registers[0]), "=b" (registers[1]), "=c" (registers[2]), "=d" (registers[3]): "a" (info));
170 #endif
171 #else
172 registers[0] = 0;
173 registers[1] = 0;
174 registers[2] = 0;
175 registers[3] = 0;
176 #endif
177 }
178
179 bool CPUID::detectMMX()
180 {
181 int registers[4];
182 cpuid(registers, 1);
183 return MMX = (registers[3] & 0x00800000) != 0;
184 }
185
186 bool CPUID::detectCMOV()
187 {
188 int registers[4];
189 cpuid(registers, 1);
190 return CMOV = (registers[3] & 0x00008000) != 0;
191 }
192
193 bool CPUID::detectSSE()
194 {
195 int registers[4];
196 cpuid(registers, 1);
197 return SSE = (registers[3] & 0x02000000) != 0;
198 }
199
200 bool CPUID::detectSSE2()
201 {
202 int registers[4];
203 cpuid(registers, 1);
204 return SSE2 = (registers[3] & 0x04000000) != 0;
205 }
206
207 bool CPUID::detectSSE3()
208 {
209 int registers[4];
210 cpuid(registers, 1);
211 return SSE3 = (registers[2] & 0x00000001) != 0;
212 }
213
214 bool CPUID::detectSSSE3()
215 {
216 int registers[4];
217 cpuid(registers, 1);
218 return SSSE3 = (registers[2] & 0x00000200) != 0;
219 }
220
221 bool CPUID::detectSSE4_1()
222 {
223 int registers[4];
224 cpuid(registers, 1);
225 return SSE4_1 = (registers[2] & 0x00080000) != 0;
226 }
227}