Repository navigation
Expand file tree
/
Copy pathutils.cpp
More file actions
150 lines (119 loc) · 3.61 KB
/
Copy pathutils.cpp
File metadata and controls
150 lines (119 loc) · 3.61 KB
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#include "utils.h"
#if COLORTWISTLIB_HAS_INTEL_INTRINSICS
#include <stdint.h>
#if defined(_MSC_VER)
# include <intrin.h>
#endif
// from https://software.intel.com/content/www/us/en/develop/articles/how-to-detect-new-instruction-support-in-the-4th-generation-intel-core-processor-family.html
static void run_cpuid(uint32_t eax, uint32_t ecx, uint32_t* abcd)
{
#if defined(_MSC_VER)
__cpuidex((int*)abcd, eax, ecx);
#else
uint32_t ebx, edx;
# if defined( __i386__ ) && defined ( __PIC__ )
/* in case of PIC under 32-bit EBX cannot be clobbered */
__asm__("movl %%ebx, %%edi \n\t cpuid \n\t xchgl %%ebx, %%edi" : "=D" (ebx),
# else
__asm__("cpuid" : "+b" (ebx),
# endif
"+a" (eax), "+c" (ecx), "=d" (edx));
abcd[0] = eax; abcd[1] = ebx; abcd[2] = ecx; abcd[3] = edx;
#endif
}
static int check_xcr0_ymm()
{
uint32_t xcr0;
#if defined(_MSC_VER)
xcr0 = (uint32_t)_xgetbv(0); /* min VS2010 SP1 compiler is required */
#else
__asm__("xgetbv" : "=a" (xcr0) : "c" (0) : "%edx");
#endif
return ((xcr0 & 6) == 6); /* checking if xmm and ymm state are enabled in XCR0 */
}
static int check_4th_gen_intel_core_features()
{
uint32_t abcd[4];
uint32_t fma_movbe_osxsave_mask = ((1 << 12) | (1 << 22) | (1 << 27));
uint32_t avx2_bmi12_mask = (1 << 5) | (1 << 3) | (1 << 8);
/* CPUID.(EAX=01H, ECX=0H):ECX.FMA[bit 12]==1 &&
CPUID.(EAX=01H, ECX=0H):ECX.MOVBE[bit 22]==1 &&
CPUID.(EAX=01H, ECX=0H):ECX.OSXSAVE[bit 27]==1 */
run_cpuid(1, 0, abcd);
if ((abcd[2] & fma_movbe_osxsave_mask) != fma_movbe_osxsave_mask)
return 0;
if (!check_xcr0_ymm())
return 0;
/* CPUID.(EAX=07H, ECX=0H):EBX.AVX2[bit 5]==1 &&
CPUID.(EAX=07H, ECX=0H):EBX.BMI1[bit 3]==1 &&
CPUID.(EAX=07H, ECX=0H):EBX.BMI2[bit 8]==1 */
run_cpuid(7, 0, abcd);
if ((abcd[1] & avx2_bmi12_mask) != avx2_bmi12_mask)
return 0;
/* CPUID.(EAX=80000001H):ECX.LZCNT[bit 5]==1 */
run_cpuid(0x80000001, 0, abcd);
if ((abcd[2] & (1 << 5)) == 0)
return 0;
return 1;
}
static int check_sse41_support()
{
uint32_t abcd[4];
constexpr uint32_t sse41_mask = (1 << 19);
run_cpuid(1, 0, abcd);
if ((abcd[2] & sse41_mask) != sse41_mask)
{
return 0;
}
return 1;
}
bool CheckWhetherCpuSupportsAVX2()
{
return check_4th_gen_intel_core_features() > 0;
}
bool CheckWhetherCpuSupportsSSE41()
{
return check_sse41_support() > 0;
}
#endif
#if COLORTWISTLIB_HASNEON
#if COLORTWISTLIB_HAS_SYS_AUXV_H
#include <sys/auxv.h>
#endif
bool CheckWhetherCpuSupportsNeon()
{
////#if COLORTWISTLIB_HAS_SYS_AUXV_H
//// #if defined(__aarch64__)
//// return (getauxval(AT_HWCAP) & (1L << 1)) != 0;
//// #elif defined(__arm__)
//// return (getauxval(AT_HWCAP) & (1L << 12)) != 0;
//// #endif
////#endif
// There seems to be no reliable way (I could find) in order to detect
// Neon-support at runtime, and it does not seem to be the "usual way" on
// ARM (to detect support at runtime).
return true;
}
#endif
#if COLORTWISTLIB_HAS_RISCV_VECTOREXTENSIONS
#if COLORTWISTLIB_HAS_SYS_AUXV_H
#include <sys/auxv.h>
// Standard HWCAP bit for Vector extension on Linux
// If your system headers are old, this might not be defined.
#ifndef COMPAT_HWCAP_ISA_V
#define COMPAT_HWCAP_ISA_V (1 << ('v' - 'a'))
#endif
#endif
bool CheckHasRiscvVectorExtensions()
{
#if COLORTWISTLIB_HAS_SYS_AUXV_H
// 1. Get Hardware Capabilities from the Kernel
unsigned long hwcap = getauxval(AT_HWCAP);
// 2. Check the 'V' bit
bool hasV = (hwcap & COMPAT_HWCAP_ISA_V);
return hasV;
#else
return true;
#endif
}
#endif