This repository has been archived by the owner on Jun 4, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathcpu.cpp
89 lines (81 loc) · 2.24 KB
/
cpu.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#include "cpu.h"
#include <cstdint>
#include <QObject>
struct CpuIdInfo
{
std::uint32_t eax, ebx, ecx, edx;
};
#if defined(_MSC_VER)
#include <intrin.h>
static CpuIdInfo GetCpuId(std::uint32_t eax, std::uint32_t ecx)
{
int info[4];
CpuIdInfo retInfo;
__cpuidex(info, eax, ecx);
retInfo.eax = info[0];
retInfo.ebx = info[1];
retInfo.ecx = info[2];
retInfo.edx = info[3];
return retInfo;
}
#elif defined(__GNUC__)
static CpuIdInfo GetCpuId(std::uint32_t eax, std::uint32_t ecx)
{
CpuIdInfo info;
asm volatile
(
"mov %1, %%eax\n\t"
"mov %2, %%ecx\n\t"
"cpuid\n\t"
"mov %%eax, (%0)\n\t"
"mov %%ebx, 4(%0)\n\t"
"mov %%ecx, 8(%0)\n\t"
"mov %%edx, 12(%0)\n\t"
: /* no output registers */
: "r"(&info), "g"(eax), "g"(ecx)
: "%eax", "%ebx", "%ecx", "%edx"
);
return info;
}
#else
#error Cannot detect compiler
#endif
static CpuIdInfo cpuFeatureInfo = GetCpuId(1, 0);
static CpuIdInfo cpuExtendedFeatureInfo = GetCpuId(0x80000001, 0);
namespace CpuId
{
template<>
bool supports(Feature feature)
{
switch (feature)
{
case Feature::Mmx:
return cpuFeatureInfo.edx & (1U << 23);
case Feature::Sse:
return cpuFeatureInfo.edx & (1U << 25);
case Feature::Sse2:
return cpuFeatureInfo.edx & (1U << 26);
case Feature::Sse3:
return cpuFeatureInfo.ecx & (1U << 0);
case Feature::Ssse3:
return cpuFeatureInfo.ecx & (1U << 9);
case Feature::Sse41:
return cpuFeatureInfo.ecx & (1U << 19);
case Feature::Sse42:
return cpuFeatureInfo.ecx & (1U << 20);
case Feature::Sse4a:
return cpuExtendedFeatureInfo.ecx & (1U << 6);
case Feature::Avx:
return cpuFeatureInfo.ecx & (1U << 28);
case Feature::Lzcnt:
return cpuExtendedFeatureInfo.ecx & (1U << 5);
case Feature::Popcnt:
return cpuFeatureInfo.ecx & (1U << 23);
case Feature::Prefetchw:
return cpuExtendedFeatureInfo.ecx & (1U << 8);
case Feature::F16c:
return cpuFeatureInfo.ecx & (1U << 29);
}
Q_UNREACHABLE();
}
}