31#if (defined(__GNUC__) || defined(__clang__)) && (defined(__i386__) || defined(__x86_64__))
32# if defined(HAVE_CPUID_H) && defined(HAVE_CPUID_COUNT)
34static void __zend_cpuid(uint32_t
func, uint32_t subfunc,
zend_cpu_info *cpuinfo) {
35 __cpuid_count(
func, subfunc, cpuinfo->eax, cpuinfo->ebx, cpuinfo->ecx, cpuinfo->edx);
38static void __zend_cpuid(uint32_t
func, uint32_t subfunc,
zend_cpu_info *cpuinfo) {
39# if defined(__i386__) && (defined(__pic__) || defined(__PIC__))
41 __asm__ __volatile__ (
46 :
"=a"(cpuinfo->eax),
"=r"(cpuinfo->ebx),
"=c"(cpuinfo->ecx),
"=d"(cpuinfo->edx)
47 :
"a"(
func),
"c"(subfunc)
50 __asm__ __volatile__ (
52 :
"=a"(cpuinfo->eax),
"=b"(cpuinfo->ebx),
"=c"(cpuinfo->ecx),
"=d"(cpuinfo->edx)
53 :
"a"(
func),
"c"(subfunc)
58#elif defined(_MSC_VER) && !defined(__clang__) && (defined(_M_X64) || defined(_M_IX86))
60static void __zend_cpuid(uint32_t
func, uint32_t subfunc,
zend_cpu_info *cpuinfo) {
63 __cpuidex(regs,
func, subfunc);
65 cpuinfo->eax = regs[0];
66 cpuinfo->ebx = regs[1];
67 cpuinfo->ecx = regs[2];
68 cpuinfo->edx = regs[3];
71static void __zend_cpuid(uint32_t
func, uint32_t subfunc,
zend_cpu_info *cpuinfo) {
76#if defined(__i386__) || defined(__x86_64__) || defined(_M_X64) || defined(_M_IX86)
78static unsigned get_xcr0_eax(
void) {
79# if defined(__GNUC__) || defined(__clang__)
84 __asm__(
".byte 0x0f, 0x01, 0xd0" :
"=a"(eax),
"=d"(edx) :
"c"(0));
86# elif defined(ZEND_WIN32) && defined(_XCR_XFEATURE_ENABLED_MASK)
87 return _xgetbv(_XCR_XFEATURE_ENABLED_MASK);
93static bool is_avx_supported(
void) {
102 if ((get_xcr0_eax() & 0x6) != 0x6) {
109static bool is_avx_supported(
void) {
116 if (!cpuinfo.initialized) {
120 cpuinfo.initialized = 1;
121 __zend_cpuid(0, 0, &cpuinfo);
122 max_feature = cpuinfo.eax;
123 if (max_feature == 0) {
127 __zend_cpuid(1, 0, &cpuinfo);
130 if (max_feature >= 7) {
131 __zend_cpuid(7, 0, &ebx);
132 cpuinfo.ebx = ebx.
ebx;
137 if (!is_avx_supported()) {
151 return (cpuinfo.ecx & feature);
ZEND_API int zend_cpu_supports(zend_cpu_feature feature)
struct _zend_cpu_info zend_cpu_info
void zend_cpu_startup(void)
@ ZEND_CPU_FEATURE_OSXSAVE
enum _zend_cpu_feature zend_cpu_feature
#define ZEND_CPU_EDX_MASK
#define ZEND_CPU_EBX_MASK