Skip to content

Commit 4f3cf98

Browse files
committed
Merge branch 'PHP-7.4' into PHP-8.0
* PHP-7.4: Fix AVX detection
2 parents 8b281e5 + 4e30ab3 commit 4f3cf98

File tree

1 file changed

+37
-0
lines changed

1 file changed

+37
-0
lines changed

Zend/zend_cpuinfo.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,38 @@ static void __zend_cpuid(uint32_t func, uint32_t subfunc, zend_cpu_info *cpuinfo
7373
}
7474
#endif
7575

76+
/* Function based on compiler-rt implementation. */
77+
static unsigned get_xcr0_eax() {
78+
#if defined(__GNUC__) || defined(__clang__)
79+
// Check xgetbv; this uses a .byte sequence instead of the instruction
80+
// directly because older assemblers do not include support for xgetbv and
81+
// there is no easy way to conditionally compile based on the assembler used.
82+
unsigned eax, edx;
83+
__asm__(".byte 0x0f, 0x01, 0xd0" : "=a"(eax), "=d"(edx) : "c"(0));
84+
return eax;
85+
#elif defined(ZEND_WIN32) && defined(_XCR_XFEATURE_ENABLED_MASK)
86+
return _xgetbv(_XCR_XFEATURE_ENABLED_MASK);
87+
#else
88+
return 0;
89+
#endif
90+
}
91+
92+
static zend_bool is_avx_supported() {
93+
if (!(cpuinfo.ecx & ZEND_CPU_FEATURE_AVX)) {
94+
/* No support for AVX */
95+
return 0;
96+
}
97+
if (!(cpuinfo.ecx & ZEND_CPU_FEATURE_OSXSAVE)) {
98+
/* The operating system does not support XSAVE. */
99+
return 0;
100+
}
101+
if ((get_xcr0_eax() & 0x6) != 0x6) {
102+
/* XCR0 SSE and AVX bits must be set. */
103+
return 0;
104+
}
105+
return 1;
106+
}
107+
76108
void zend_cpu_startup(void)
77109
{
78110
if (!cpuinfo.initialized) {
@@ -95,6 +127,11 @@ void zend_cpu_startup(void)
95127
} else {
96128
cpuinfo.ebx = 0;
97129
}
130+
131+
if (!is_avx_supported()) {
132+
cpuinfo.edx &= ~ZEND_CPU_FEATURE_AVX;
133+
cpuinfo.ebx &= ~(ZEND_CPU_FEATURE_AVX2 & ~ZEND_CPU_EBX_MASK);
134+
}
98135
}
99136
}
100137

0 commit comments

Comments
 (0)