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 #ifndef sw_CPUID_hpp
16 #define sw_CPUID_hpp
17 
18 namespace sw
19 {
20 	#if !defined(__x86_64__) && (defined(_M_AMD64) || defined (_M_X64))
21 		#define __x86_64__ 1
22 	#endif
23 
24 	class CPUID
25 	{
26 	public:
27 		static bool supportsMMX();
28 		static bool supportsCMOV();
29 		static bool supportsMMX2();   // MMX instructions added by SSE: pshufw, pmulhuw, pmovmskb, pavgw/b, pextrw, pinsrw, pmaxsw/ub, etc.
30 		static bool supportsSSE();
31 		static bool supportsSSE2();
32 		static bool supportsSSE3();
33 		static bool supportsSSSE3();
34 		static bool supportsSSE4_1();
35 		static int coreCount();
36 		static int processAffinity();
37 
38 		static void setEnableMMX(bool enable);
39 		static void setEnableCMOV(bool enable);
40 		static void setEnableSSE(bool enable);
41 		static void setEnableSSE2(bool enable);
42 		static void setEnableSSE3(bool enable);
43 		static void setEnableSSSE3(bool enable);
44 		static void setEnableSSE4_1(bool enable);
45 
46 		static void setFlushToZero(bool enable);        // Denormal results are written as zero
47 		static void setDenormalsAreZero(bool enable);   // Denormal inputs are read as zero
48 
49 	private:
50 		static bool MMX;
51 		static bool CMOV;
52 		static bool SSE;
53 		static bool SSE2;
54 		static bool SSE3;
55 		static bool SSSE3;
56 		static bool SSE4_1;
57 		static int cores;
58 		static int affinity;
59 
60 		static bool enableMMX;
61 		static bool enableCMOV;
62 		static bool enableSSE;
63 		static bool enableSSE2;
64 		static bool enableSSE3;
65 		static bool enableSSSE3;
66 		static bool enableSSE4_1;
67 
68 		static bool detectMMX();
69 		static bool detectCMOV();
70 		static bool detectSSE();
71 		static bool detectSSE2();
72 		static bool detectSSE3();
73 		static bool detectSSSE3();
74 		static bool detectSSE4_1();
75 		static int detectCoreCount();
76 		static int detectAffinity();
77 	};
78 }
79 
80 namespace sw
81 {
supportsMMX()82 	inline bool CPUID::supportsMMX()
83 	{
84 		return MMX && enableMMX;
85 	}
86 
supportsCMOV()87 	inline bool CPUID::supportsCMOV()
88 	{
89 		return CMOV && enableCMOV;
90 	}
91 
supportsMMX2()92 	inline bool CPUID::supportsMMX2()
93 	{
94 		return supportsSSE();   // Coincides with 64-bit integer vector instructions supported by SSE
95 	}
96 
supportsSSE()97 	inline bool CPUID::supportsSSE()
98 	{
99 		return SSE && enableSSE;
100 	}
101 
supportsSSE2()102 	inline bool CPUID::supportsSSE2()
103 	{
104 		return SSE2 && enableSSE2;
105 	}
106 
supportsSSE3()107 	inline bool CPUID::supportsSSE3()
108 	{
109 		return SSE3 && enableSSE3;
110 	}
111 
supportsSSSE3()112 	inline bool CPUID::supportsSSSE3()
113 	{
114 		return SSSE3 && enableSSSE3;
115 	}
116 
supportsSSE4_1()117 	inline bool CPUID::supportsSSE4_1()
118 	{
119 		return SSE4_1 && enableSSE4_1;
120 	}
121 
coreCount()122 	inline int CPUID::coreCount()
123 	{
124 		return cores;
125 	}
126 
processAffinity()127 	inline int CPUID::processAffinity()
128 	{
129 		return affinity;
130 	}
131 }
132 
133 #endif   // sw_CPUID_hpp
134