|
1
|
1 #include "pfc-lite.h"
|
|
|
2 #include "cpuid.h"
|
|
|
3
|
|
|
4
|
|
|
5 #ifdef _MSC_VER
|
|
|
6 #include <intrin.h>
|
|
|
7 #endif
|
|
|
8
|
|
|
9 #if PFC_HAVE_CPUID
|
|
|
10 namespace pfc {
|
|
|
11
|
|
|
12 bool query_cpu_feature_set(unsigned p_value) {
|
|
|
13
|
|
|
14 #ifdef __AVX__
|
|
|
15 // AVX implies all supported values are set
|
|
|
16 return true;
|
|
|
17 #else
|
|
|
18
|
|
|
19 #if _M_IX86_FP >= 2 || defined(_M_X64)
|
|
|
20 // don't bother checking for SSE/SSE2 if compiled to use them
|
|
|
21 p_value &= ~(CPU_HAVE_SSE | CPU_HAVE_SSE2);
|
|
|
22 if (p_value == 0) return true;
|
|
|
23 #endif
|
|
|
24
|
|
|
25 #ifdef _MSC_VER
|
|
|
26 __try {
|
|
|
27 #endif
|
|
|
28 if (p_value & (CPU_HAVE_SSE | CPU_HAVE_SSE2 | CPU_HAVE_SSE3 | CPU_HAVE_SSSE3 | CPU_HAVE_SSE41 | CPU_HAVE_SSE42 | CPU_HAVE_AVX)) {
|
|
|
29 int buffer[4];
|
|
|
30 __cpuid(buffer,1);
|
|
|
31 if (p_value & CPU_HAVE_SSE) {
|
|
|
32 if ((buffer[3]&(1<<25)) == 0) return false;
|
|
|
33 }
|
|
|
34 if (p_value & CPU_HAVE_SSE2) {
|
|
|
35 if ((buffer[3]&(1<<26)) == 0) return false;
|
|
|
36 }
|
|
|
37 if (p_value & CPU_HAVE_SSE3) {
|
|
|
38 if ((buffer[2]&(1<<0)) == 0) return false;
|
|
|
39 }
|
|
|
40 if (p_value & CPU_HAVE_SSSE3) {
|
|
|
41 if ((buffer[2]&(1<<9)) == 0) return false;
|
|
|
42 }
|
|
|
43 if (p_value & CPU_HAVE_SSE41) {
|
|
|
44 if ((buffer[2]&(1<<19)) == 0) return false;
|
|
|
45 }
|
|
|
46 if (p_value & CPU_HAVE_SSE42) {
|
|
|
47 if ((buffer[2]&(1<<20)) == 0) return false;
|
|
|
48 }
|
|
|
49 if (p_value & CPU_HAVE_AVX) {
|
|
|
50 if ((buffer[2] & (1 << 28)) == 0) return false;
|
|
|
51 }
|
|
|
52 }
|
|
|
53 return true;
|
|
|
54 #ifdef _MSC_VER
|
|
|
55 } __except(1) {
|
|
|
56 return false;
|
|
|
57 }
|
|
|
58 #endif
|
|
|
59 #endif
|
|
|
60 }
|
|
|
61 }
|
|
|
62
|
|
|
63 #endif
|
|
|
64
|
|
|
65 namespace pfc {
|
|
|
66 const char* cpuArch() {
|
|
|
67 #ifdef PFC_CPU_ARCH
|
|
|
68 return PFC_CPU_ARCH;
|
|
|
69 #else
|
|
|
70 return "Unknown";
|
|
|
71 #endif
|
|
|
72 }
|
|
|
73 }
|