diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2020-11-27 14:49:45 +0100 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2020-11-27 14:49:45 +0100 |
commit | 4f3cf983dcdab2e5443d621894f1c52c1847749e (patch) | |
tree | 8cc08075b3615bd9ba2c71cc5775ad53a1bb6f2d /Zend | |
parent | 8b281e5b6b0295cab936682134d24bf5bb2d537d (diff) | |
parent | 4e30ab33d84232ba2686e7ed5b125861db63142d (diff) | |
download | php-git-4f3cf983dcdab2e5443d621894f1c52c1847749e.tar.gz |
Merge branch 'PHP-7.4' into PHP-8.0
* PHP-7.4:
Fix AVX detection
Diffstat (limited to 'Zend')
-rw-r--r-- | Zend/zend_cpuinfo.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/Zend/zend_cpuinfo.c b/Zend/zend_cpuinfo.c index 81e3f43c51..1b268931ed 100644 --- a/Zend/zend_cpuinfo.c +++ b/Zend/zend_cpuinfo.c @@ -73,6 +73,38 @@ static void __zend_cpuid(uint32_t func, uint32_t subfunc, zend_cpu_info *cpuinfo } #endif +/* Function based on compiler-rt implementation. */ +static unsigned get_xcr0_eax() { +#if defined(__GNUC__) || defined(__clang__) + // Check xgetbv; this uses a .byte sequence instead of the instruction + // directly because older assemblers do not include support for xgetbv and + // there is no easy way to conditionally compile based on the assembler used. + unsigned eax, edx; + __asm__(".byte 0x0f, 0x01, 0xd0" : "=a"(eax), "=d"(edx) : "c"(0)); + return eax; +#elif defined(ZEND_WIN32) && defined(_XCR_XFEATURE_ENABLED_MASK) + return _xgetbv(_XCR_XFEATURE_ENABLED_MASK); +#else + return 0; +#endif +} + +static zend_bool is_avx_supported() { + if (!(cpuinfo.ecx & ZEND_CPU_FEATURE_AVX)) { + /* No support for AVX */ + return 0; + } + if (!(cpuinfo.ecx & ZEND_CPU_FEATURE_OSXSAVE)) { + /* The operating system does not support XSAVE. */ + return 0; + } + if ((get_xcr0_eax() & 0x6) != 0x6) { + /* XCR0 SSE and AVX bits must be set. */ + return 0; + } + return 1; +} + void zend_cpu_startup(void) { if (!cpuinfo.initialized) { @@ -95,6 +127,11 @@ void zend_cpu_startup(void) } else { cpuinfo.ebx = 0; } + + if (!is_avx_supported()) { + cpuinfo.edx &= ~ZEND_CPU_FEATURE_AVX; + cpuinfo.ebx &= ~(ZEND_CPU_FEATURE_AVX2 & ~ZEND_CPU_EBX_MASK); + } } } |