• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // 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 
30 namespace 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 
setEnableMMX(bool enable)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 
setEnableCMOV(bool enable)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 
setEnableSSE(bool enable)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 
setEnableSSE2(bool enable)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 
setEnableSSE3(bool enable)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 
setEnableSSSE3(bool enable)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 
setEnableSSE4_1(bool enable)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 
cpuid(int registers[4],int info)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"
170 	               : "=a"(registers[0]), "=b"(registers[1]), "=c"(registers[2]), "=d"(registers[3])
171 	               : "a"(info));
172 #	endif
173 #else
174 	registers[0] = 0;
175 	registers[1] = 0;
176 	registers[2] = 0;
177 	registers[3] = 0;
178 #endif
179 }
180 
detectMMX()181 bool CPUID::detectMMX()
182 {
183 	int registers[4];
184 	cpuid(registers, 1);
185 	return MMX = (registers[3] & 0x00800000) != 0;
186 }
187 
detectCMOV()188 bool CPUID::detectCMOV()
189 {
190 	int registers[4];
191 	cpuid(registers, 1);
192 	return CMOV = (registers[3] & 0x00008000) != 0;
193 }
194 
detectSSE()195 bool CPUID::detectSSE()
196 {
197 	int registers[4];
198 	cpuid(registers, 1);
199 	return SSE = (registers[3] & 0x02000000) != 0;
200 }
201 
detectSSE2()202 bool CPUID::detectSSE2()
203 {
204 	int registers[4];
205 	cpuid(registers, 1);
206 	return SSE2 = (registers[3] & 0x04000000) != 0;
207 }
208 
detectSSE3()209 bool CPUID::detectSSE3()
210 {
211 	int registers[4];
212 	cpuid(registers, 1);
213 	return SSE3 = (registers[2] & 0x00000001) != 0;
214 }
215 
detectSSSE3()216 bool CPUID::detectSSSE3()
217 {
218 	int registers[4];
219 	cpuid(registers, 1);
220 	return SSSE3 = (registers[2] & 0x00000200) != 0;
221 }
222 
detectSSE4_1()223 bool CPUID::detectSSE4_1()
224 {
225 	int registers[4];
226 	cpuid(registers, 1);
227 	return SSE4_1 = (registers[2] & 0x00080000) != 0;
228 }
229 
230 }  // namespace rr
231