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