8 #elif defined(HAVE_GCC_GET_CPUID) && defined(USE_GCC_GET_CPUID) 13 #define CPUID_AVX2_BIT 0x20 // Bit 5 of EBX for EAX=0x7 14 #define CPUID_AVX_BIT 0x10000000 // Bit 28 of ECX for EAX=0x1 15 #define CPUID_SSE_BIT 0x2000000 // bit 25 of EDX for EAX=0x1 18 #define FUNCTION_IMPL(NAME, EXT) \ 23 #define INIT_DISPATCH_PTR(OP) \ 26 for (i = 0; i < sizeof(THVector_(OP ## _DISPATCHTABLE)) / sizeof(FunctionDescription); ++i) { \ 27 THVector_(OP ## _DISPATCHPTR) = reinterpret_cast<decltype(THVector_(OP ## _DISPATCHPTR))>(THVector_(OP ## _DISPATCHTABLE)[i].function); \ 28 if (THVector_(OP ## _DISPATCHTABLE)[i].supportedSimdExt & hostSimdExts) { \ 38 uint32_t supportedSimdExt;
45 SIMDExtension_NEON = 0x1,
46 #elif defined(__PPC64__) 47 SIMDExtension_VSX = 0x1,
49 SIMDExtension_AVX2 = 0x1,
50 SIMDExtension_AVX = 0x2,
51 SIMDExtension_SSE = 0x4,
53 SIMDExtension_DEFAULT = 0x0
57 #if defined(__arm__) || defined(__aarch64__) // incl. armel, armhf, arm64 61 static inline uint32_t detectHostSIMDExtensions()
63 return SIMDExtension_NEON;
66 #else //ARM without NEON 68 static inline uint32_t detectHostSIMDExtensions()
70 return SIMDExtension_DEFAULT;
75 #elif defined(__PPC64__) 79 static inline uint32_t detectHostSIMDExtensions()
81 uint32_t hostSimdExts = SIMDExtension_DEFAULT;
84 evar = getenv(
"TH_NO_VSX");
85 if (evar == NULL || strncmp(evar,
"1", 1) != 0)
86 hostSimdExts = SIMDExtension_VSX;
90 #else //PPC64 without VSX 92 static inline uint32_t detectHostSIMDExtensions()
94 return SIMDExtension_DEFAULT;
99 #elif defined(__EMSCRIPTEN__) 101 static inline uint32_t detectHostSIMDExtensions()
103 return SIMDExtension_DEFAULT;
107 static inline void cpuid(uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
109 #if defined(_MSC_VER) 111 __cpuid((
int *)cpuInfo, *eax);
116 #elif defined(HAVE_GCC_GET_CPUID) && defined(USE_GCC_GET_CPUID) 117 uint32_t level = *eax;
118 __get_cpuid (level, eax, ebx, ecx, edx);
120 uint32_t a = *eax, b, c = *ecx, d;
121 asm volatile (
"cpuid\n\t" 122 :
"+a"(a),
"=b"(b),
"+c"(c),
"=d"(d) );
130 static inline uint32_t detectHostSIMDExtensions()
132 uint32_t eax, ebx, ecx, edx;
133 uint32_t hostSimdExts = 0x0;
134 int TH_NO_AVX = 1, TH_NO_AVX2 = 1, TH_NO_SSE = 1;
137 evar = getenv(
"TH_NO_AVX2");
138 if (evar == NULL || strncmp(evar,
"1", 1) != 0)
144 cpuid(&eax, &ebx, &ecx, &edx);
145 if ((ebx & CPUID_AVX2_BIT) && TH_NO_AVX2 == 0) {
146 hostSimdExts |= SIMDExtension_AVX2;
151 cpuid(&eax, &ebx, &ecx, &edx);
153 evar = getenv(
"TH_NO_AVX");
154 if (evar == NULL || strncmp(evar,
"1", 1) != 0)
156 if (ecx & CPUID_AVX_BIT && TH_NO_AVX == 0) {
157 hostSimdExts |= SIMDExtension_AVX;
160 evar = getenv(
"TH_NO_SSE");
161 if (evar == NULL || strncmp(evar,
"1", 1) != 0)
163 if (edx & CPUID_SSE_BIT && TH_NO_SSE == 0) {
164 hostSimdExts |= SIMDExtension_SSE;
170 #endif // end SIMD extension detection code