diff options
author | Xinchen Hui <laruence@gmail.com> | 2018-02-10 17:37:38 +0800 |
---|---|---|
committer | Xinchen Hui <laruence@gmail.com> | 2018-02-10 17:38:30 +0800 |
commit | 08428cf6a77d360b52028d6ddfe1409218e391db (patch) | |
tree | 34c4db557c8353f08da3158320baaa75ed8bda0c /Zend | |
parent | 7ce72f0cf5c0b5bc458bee90698e19fb417d8b96 (diff) | |
download | php-git-08428cf6a77d360b52028d6ddfe1409218e391db.tar.gz |
Fixed cpuinfo in LLVM GCC & Added AVX2 detection
Seems it only defines __builtin_cpu_supports but no __builtin_cpu_init
(Apple LLVM version 9.0.0 (clang-900.0.38))
Diffstat (limited to 'Zend')
-rw-r--r-- | Zend/zend.c | 1 | ||||
-rw-r--r-- | Zend/zend_cpuinfo.c | 29 | ||||
-rw-r--r-- | Zend/zend_cpuinfo.h | 24 |
3 files changed, 39 insertions, 15 deletions
diff --git a/Zend/zend.c b/Zend/zend.c index dc0cab8cc0..e62f9e1a48 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -743,6 +743,7 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions) / #endif zend_cpu_startup(); + zend_cpu_supports(ZEND_CPU_FEATURE_AVX2); #ifdef ZEND_WIN32 php_win32_cp_set_by_id(65001); diff --git a/Zend/zend_cpuinfo.c b/Zend/zend_cpuinfo.c index 988ceb2521..43252a7cca 100644 --- a/Zend/zend_cpuinfo.c +++ b/Zend/zend_cpuinfo.c @@ -29,46 +29,53 @@ typedef struct _zend_cpu_info { static zend_cpu_info cpuinfo = {0}; #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) -static void __zend_cpuid(uint32_t func, uint32_t subfunc) { +static void __zend_cpuid(uint32_t func, uint32_t subfunc, zend_cpu_info *cpuinfo) { __asm__ __volatile__ ( "cpuid" - : "=a"(cpuinfo.eax), "=b"(cpuinfo.ebx), "=c"(cpuinfo.ecx), "=d"(cpuinfo.edx) + : "=a"(cpuinfo->eax), "=b"(cpuinfo->ebx), "=c"(cpuinfo->ecx), "=d"(cpuinfo->edx) : "a"(func), "c"(subfunc) ); } #elif defined(ZEND_WIN32) # include <intrin.h> -static void __zend_cpuid(uint32_t func, uint32_t subfunc) { +static void __zend_cpuid(uint32_t func, uint32_t subfunc, zend_cpu_info *cpuinfo) { int regs[4]; __cpuidex(regs, func, subfunc); - cpuinfo.eax = regs[0]; - cpuinfo.ebx = regs[1]; - cpuinfo.ecx = regs[2]; - cpuinfo.edx = regs[3]; + cpuinfo->eax = regs[0]; + cpuinfo->ebx = regs[1]; + cpuinfo->ecx = regs[2]; + cpuinfo->edx = regs[3]; } #else -static void __zend_cpuid(uint32_t func, uint32_t subfunc) { - cpuinfo.eax = 0; +static void __zend_cpuid(uint32_t func, uint32_t subfunc, zend_cpu_info *cpuinfo) { + cpuinfo->eax = 0; } #endif void zend_cpu_startup(void) { if (!cpuinfo.initialized) { + zend_cpu_info ebx; + cpuinfo.initialized = 1; - __zend_cpuid(0, 0); + __zend_cpuid(0, 0, &cpuinfo); if (cpuinfo.eax == 0) { return; } - __zend_cpuid(1, 0); + __zend_cpuid(1, 0, &cpuinfo); + /* for avx2 */ + __zend_cpuid(7, 0, &ebx); + cpuinfo.ebx = ebx.ebx; } } ZEND_API int zend_cpu_supports(zend_cpu_feature feature) { if (feature & ZEND_CPU_EDX_MASK) { return (cpuinfo.edx & (feature & ~ZEND_CPU_EDX_MASK)); + } else if (feature & ZEND_CPU_EBX_MASK) { + return (cpuinfo.ebx & (feature & ~ZEND_CPU_EBX_MASK)); } else { return (cpuinfo.ecx & feature); } diff --git a/Zend/zend_cpuinfo.h b/Zend/zend_cpuinfo.h index c077366bd8..d0d3a936e1 100644 --- a/Zend/zend_cpuinfo.h +++ b/Zend/zend_cpuinfo.h @@ -21,6 +21,7 @@ #include "zend.h" +#define ZEND_CPU_EBX_MASK (1<<30) #define ZEND_CPU_EDX_MASK (1<<31) typedef enum _zend_cpu_feature { @@ -55,9 +56,12 @@ typedef enum _zend_cpu_feature { ZEND_CPU_FEATURE_OSXSAVE = (1<<27) , ZEND_CPU_FEATURE_AVX = (1<<28), ZEND_CPU_FEATURE_F16C = (1<<29), - ZEND_CPU_FEATURE_RDRAND = (1<<30), + /* intentionally don't support = (1<<30) */ /* intentionally don't support = (1<<31) */ + /* EBX */ + ZEND_CPU_FEATURE_AVX2 = (1<<5 | ZEND_CPU_EBX_MASK), + /* EDX */ ZEND_CPU_FEATURE_FPU = (1<<0 | ZEND_CPU_EDX_MASK), ZEND_CPU_FEATURE_VME = (1<<1 | ZEND_CPU_EDX_MASK), @@ -88,47 +92,59 @@ typedef enum _zend_cpu_feature { ZEND_CPU_FEATURE_SSE2 = (1<<26 | ZEND_CPU_EDX_MASK), ZEND_CPU_FEATURE_SS = (1<<27 | ZEND_CPU_EDX_MASK), ZEND_CPU_FEATURE_HT = (1<<28 | ZEND_CPU_EDX_MASK), - ZEND_CPU_FEATURE_TM = (1<<29 | ZEND_CPU_EDX_MASK), - ZEND_CPU_FEATURE_IA64 = (1<<30 | ZEND_CPU_EDX_MASK) + ZEND_CPU_FEATURE_TM = (1<<29 | ZEND_CPU_EDX_MASK) + /*intentionally don't support = (1<<30 | ZEND_CPU_EDX_MASK)*/ /*intentionally don't support = (1<<31 | ZEND_CPU_EDX_MASK)*/ } zend_cpu_feature; void zend_cpu_startup(); ZEND_API int zend_cpu_supports(zend_cpu_feature feature); -#ifdef PHP_HAVE_BUILTIN_CPU_SUPPORTS +#if PHP_HAVE_BUILTIN_CPU_SUPPORTS /* NOTE: you should use following inline function in * resolver functions (ifunc), as it could be called * before all PLT symbols are resloved. in other words, * resolver functions should not depends any external * functions */ static zend_always_inline int zend_cpu_support_sse2() { +#if PHP_HAVE_BUILTIN_CPU_INIT __builtin_cpu_init(); +#endif return __builtin_cpu_supports("sse2"); } static zend_always_inline int zend_cpu_support_sse3() { +#if PHP_HAVE_BUILTIN_CPU_INIT __builtin_cpu_init(); +#endif return __builtin_cpu_supports("sse3"); } static zend_always_inline int zend_cpu_support_sse41() { +#if PHP_HAVE_BUILTIN_CPU_INIT __builtin_cpu_init(); +#endif return __builtin_cpu_supports("sse4.1"); } static zend_always_inline int zend_cpu_support_sse42() { +#if PHP_HAVE_BUILTIN_CPU_INIT __builtin_cpu_init(); +#endif return __builtin_cpu_supports("sse4.2"); } static zend_always_inline int zend_cpu_support_avx() { +#if PHP_HAVE_BUILTIN_CPU_INIT __builtin_cpu_init(); +#endif return __builtin_cpu_supports("avx"); } static zend_always_inline int zend_cpu_support_avx2() { +#if PHP_HAVE_BUILTIN_CPU_INIT __builtin_cpu_init(); +#endif return __builtin_cpu_supports("avx2"); } #else |