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 }  // namespace sw
84 
85 /* Inline implementation */
86 
87 namespace sw {
88 
supportsMMX()89 inline bool CPUID::supportsMMX()
90 {
91 	return MMX && enableMMX;
92 }
93 
supportsCMOV()94 inline bool CPUID::supportsCMOV()
95 {
96 	return CMOV && enableCMOV;
97 }
98 
supportsMMX2()99 inline bool CPUID::supportsMMX2()
100 {
101 	return supportsSSE();  // Coincides with 64-bit integer vector instructions supported by SSE
102 }
103 
supportsSSE()104 inline bool CPUID::supportsSSE()
105 {
106 	return SSE && enableSSE;
107 }
108 
supportsSSE2()109 inline bool CPUID::supportsSSE2()
110 {
111 	return SSE2 && enableSSE2;
112 }
113 
supportsSSE3()114 inline bool CPUID::supportsSSE3()
115 {
116 	return SSE3 && enableSSE3;
117 }
118 
supportsSSSE3()119 inline bool CPUID::supportsSSSE3()
120 {
121 	return SSSE3 && enableSSSE3;
122 }
123 
supportsSSE4_1()124 inline bool CPUID::supportsSSE4_1()
125 {
126 	return SSE4_1 && enableSSE4_1;
127 }
128 
coreCount()129 inline int CPUID::coreCount()
130 {
131 	return cores;
132 }
133 
processAffinity()134 inline int CPUID::processAffinity()
135 {
136 	return affinity;
137 }
138 
139 }  // namespace sw
140 
141 #endif  // sw_CPUID_hpp
142