1 ///////////////////////////////////////////////////////////////////////////////
2 // MuldeR's Utilities for Qt
3 // Copyright (C) 2004-2014 LoRd_MuldeR <MuldeR2@GMX.de>
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU Lesser General Public
7 // License as published by the Free Software Foundation; either
8 // version 2.1 of the License, or (at your option) any later version.
10 // This library is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // Lesser General Public License for more details.
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with this library; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 // http://www.gnu.org/licenses/lgpl-2.1.txt
20 //////////////////////////////////////////////////////////////////////////////////
23 #define WIN32_LEAN_AND_MEAN 1
27 #include <MUtils/CPUFeatures.h>
28 #include <MUtils/OSSupport.h>
33 MUtils::CPUFetaures::cpu_info_t
MUtils::CPUFetaures::detect(void)
35 const OS::ArgumentMap
&args
= OS::arguments();
36 typedef BOOL (WINAPI
*IsWow64ProcessFun
)(__in HANDLE hProcess
, __out PBOOL Wow64Process
);
39 SYSTEM_INFO systemInfo
;
40 int CPUInfo
[4] = {-1};
41 char CPUIdentificationString
[0x40];
42 char CPUBrandString
[0x40];
44 memset(&features
, 0, sizeof(cpu_info_t
));
45 memset(&systemInfo
, 0, sizeof(SYSTEM_INFO
));
46 memset(CPUIdentificationString
, 0, sizeof(CPUIdentificationString
));
47 memset(CPUBrandString
, 0, sizeof(CPUBrandString
));
50 memcpy(CPUIdentificationString
, &CPUInfo
[1], sizeof(int));
51 memcpy(CPUIdentificationString
+ 4, &CPUInfo
[3], sizeof(int));
52 memcpy(CPUIdentificationString
+ 8, &CPUInfo
[2], sizeof(int));
53 features
.intel
= (_stricmp(CPUIdentificationString
, "GenuineIntel") == 0);
54 strncpy_s(features
.vendor
, 0x40, CPUIdentificationString
, _TRUNCATE
);
59 if(CPUInfo
[3] & 0x00800000) features
.features
|= FLAG_MMX
;
60 if(CPUInfo
[3] & 0x02000000) features
.features
|= FLAG_SSE
;
61 if(CPUInfo
[3] & 0x04000000) features
.features
|= FLAG_SSE2
;
62 if(CPUInfo
[2] & 0x00000001) features
.features
|= FLAG_SSE3
;
63 if(CPUInfo
[2] & 0x00000200) features
.features
|= FLAG_SSSE3
;
64 if(CPUInfo
[2] & 0x00080000) features
.features
|= FLAG_SSE4
;
65 if(CPUInfo
[2] & 0x00100000) features
.features
|= FLAG_SSE42
;
66 features
.stepping
= CPUInfo
[0] & 0xf;
67 features
.model
= ((CPUInfo
[0] >> 4) & 0xf) + (((CPUInfo
[0] >> 16) & 0xf) << 4);
68 features
.family
= ((CPUInfo
[0] >> 8) & 0xf) + ((CPUInfo
[0] >> 20) & 0xff);
71 __cpuid(CPUInfo
, 0x80000000);
72 int nExIds
= qMax
<int>(qMin
<int>(CPUInfo
[0], 0x80000004), 0x80000000);
74 for(int i
= 0x80000002; i
<= nExIds
; ++i
)
80 memcpy(CPUBrandString
, CPUInfo
, sizeof(CPUInfo
));
83 memcpy(CPUBrandString
+ 16, CPUInfo
, sizeof(CPUInfo
));
86 memcpy(CPUBrandString
+ 32, CPUInfo
, sizeof(CPUInfo
));
91 strncpy_s(features
.brand
, 0x40, CPUBrandString
, _TRUNCATE
);
93 if(strlen(features
.brand
) < 1) strncpy_s(features
.brand
, 0x40, "Unknown", _TRUNCATE
);
94 if(strlen(features
.vendor
) < 1) strncpy_s(features
.vendor
, 0x40, "Unknown", _TRUNCATE
);
96 #if (!(defined(_M_X64) || defined(_M_IA64)))
97 QLibrary
Kernel32Lib("kernel32.dll");
98 if(IsWow64ProcessFun IsWow64ProcessPtr
= (IsWow64ProcessFun
) Kernel32Lib
.resolve("IsWow64Process"))
100 BOOL x64flag
= FALSE
;
101 if(IsWow64ProcessPtr(GetCurrentProcess(), &x64flag
))
103 features
.x64
= (x64flag
== TRUE
);
110 DWORD_PTR procAffinity
, sysAffinity
;
111 if(GetProcessAffinityMask(GetCurrentProcess(), &procAffinity
, &sysAffinity
))
113 for(DWORD_PTR mask
= 1; mask
; mask
<<= 1)
115 features
.count
+= ((sysAffinity
& mask
) ? (1) : (0));
118 if(features
.count
< 1)
120 GetNativeSystemInfo(&systemInfo
);
121 features
.count
= qBound(1UL, systemInfo
.dwNumberOfProcessors
, 64UL);
125 if(args
.contains("force-cpu-no-64bit")) { flag
= true; features
.x64
= false; }
126 if(args
.contains("force-cpu-no-sse" )) { flag
= true; features
.features
&= (~(FLAG_SSE
| FLAG_SSE2
| FLAG_SSE3
| FLAG_SSSE3
| FLAG_SSE4
| FLAG_SSE42
)); }
127 if(args
.contains("force-cpu-no-intel")) { flag
= true; features
.intel
= false; }
131 qWarning("CPU flags overwritten by user-defined parameters. Take care!\n");