Skip to content

Commit 08428cf

Browse files
committed
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))
1 parent 7ce72f0 commit 08428cf

File tree

4 files changed

+41
-15
lines changed

4 files changed

+41
-15
lines changed

Zend/zend.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -743,6 +743,7 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions) /
743743
#endif
744744

745745
zend_cpu_startup();
746+
zend_cpu_supports(ZEND_CPU_FEATURE_AVX2);
746747

747748
#ifdef ZEND_WIN32
748749
php_win32_cp_set_by_id(65001);

Zend/zend_cpuinfo.c

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,46 +29,53 @@ typedef struct _zend_cpu_info {
2929
static zend_cpu_info cpuinfo = {0};
3030

3131
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
32-
static void __zend_cpuid(uint32_t func, uint32_t subfunc) {
32+
static void __zend_cpuid(uint32_t func, uint32_t subfunc, zend_cpu_info *cpuinfo) {
3333
__asm__ __volatile__ (
3434
"cpuid"
35-
: "=a"(cpuinfo.eax), "=b"(cpuinfo.ebx), "=c"(cpuinfo.ecx), "=d"(cpuinfo.edx)
35+
: "=a"(cpuinfo->eax), "=b"(cpuinfo->ebx), "=c"(cpuinfo->ecx), "=d"(cpuinfo->edx)
3636
: "a"(func), "c"(subfunc)
3737
);
3838
}
3939
#elif defined(ZEND_WIN32)
4040
# include <intrin.h>
41-
static void __zend_cpuid(uint32_t func, uint32_t subfunc) {
41+
static void __zend_cpuid(uint32_t func, uint32_t subfunc, zend_cpu_info *cpuinfo) {
4242
int regs[4];
4343

4444
__cpuidex(regs, func, subfunc);
4545

46-
cpuinfo.eax = regs[0];
47-
cpuinfo.ebx = regs[1];
48-
cpuinfo.ecx = regs[2];
49-
cpuinfo.edx = regs[3];
46+
cpuinfo->eax = regs[0];
47+
cpuinfo->ebx = regs[1];
48+
cpuinfo->ecx = regs[2];
49+
cpuinfo->edx = regs[3];
5050
}
5151
#else
52-
static void __zend_cpuid(uint32_t func, uint32_t subfunc) {
53-
cpuinfo.eax = 0;
52+
static void __zend_cpuid(uint32_t func, uint32_t subfunc, zend_cpu_info *cpuinfo) {
53+
cpuinfo->eax = 0;
5454
}
5555
#endif
5656

5757
void zend_cpu_startup(void)
5858
{
5959
if (!cpuinfo.initialized) {
60+
zend_cpu_info ebx;
61+
6062
cpuinfo.initialized = 1;
61-
__zend_cpuid(0, 0);
63+
__zend_cpuid(0, 0, &cpuinfo);
6264
if (cpuinfo.eax == 0) {
6365
return;
6466
}
65-
__zend_cpuid(1, 0);
67+
__zend_cpuid(1, 0, &cpuinfo);
68+
/* for avx2 */
69+
__zend_cpuid(7, 0, &ebx);
70+
cpuinfo.ebx = ebx.ebx;
6671
}
6772
}
6873

6974
ZEND_API int zend_cpu_supports(zend_cpu_feature feature) {
7075
if (feature & ZEND_CPU_EDX_MASK) {
7176
return (cpuinfo.edx & (feature & ~ZEND_CPU_EDX_MASK));
77+
} else if (feature & ZEND_CPU_EBX_MASK) {
78+
return (cpuinfo.ebx & (feature & ~ZEND_CPU_EBX_MASK));
7279
} else {
7380
return (cpuinfo.ecx & feature);
7481
}

Zend/zend_cpuinfo.h

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include "zend.h"
2323

24+
#define ZEND_CPU_EBX_MASK (1<<30)
2425
#define ZEND_CPU_EDX_MASK (1<<31)
2526

2627
typedef enum _zend_cpu_feature {
@@ -55,9 +56,12 @@ typedef enum _zend_cpu_feature {
5556
ZEND_CPU_FEATURE_OSXSAVE = (1<<27) ,
5657
ZEND_CPU_FEATURE_AVX = (1<<28),
5758
ZEND_CPU_FEATURE_F16C = (1<<29),
58-
ZEND_CPU_FEATURE_RDRAND = (1<<30),
59+
/* intentionally don't support = (1<<30) */
5960
/* intentionally don't support = (1<<31) */
6061

62+
/* EBX */
63+
ZEND_CPU_FEATURE_AVX2 = (1<<5 | ZEND_CPU_EBX_MASK),
64+
6165
/* EDX */
6266
ZEND_CPU_FEATURE_FPU = (1<<0 | ZEND_CPU_EDX_MASK),
6367
ZEND_CPU_FEATURE_VME = (1<<1 | ZEND_CPU_EDX_MASK),
@@ -88,47 +92,59 @@ typedef enum _zend_cpu_feature {
8892
ZEND_CPU_FEATURE_SSE2 = (1<<26 | ZEND_CPU_EDX_MASK),
8993
ZEND_CPU_FEATURE_SS = (1<<27 | ZEND_CPU_EDX_MASK),
9094
ZEND_CPU_FEATURE_HT = (1<<28 | ZEND_CPU_EDX_MASK),
91-
ZEND_CPU_FEATURE_TM = (1<<29 | ZEND_CPU_EDX_MASK),
92-
ZEND_CPU_FEATURE_IA64 = (1<<30 | ZEND_CPU_EDX_MASK)
95+
ZEND_CPU_FEATURE_TM = (1<<29 | ZEND_CPU_EDX_MASK)
96+
/*intentionally don't support = (1<<30 | ZEND_CPU_EDX_MASK)*/
9397
/*intentionally don't support = (1<<31 | ZEND_CPU_EDX_MASK)*/
9498
} zend_cpu_feature;
9599

96100
void zend_cpu_startup();
97101
ZEND_API int zend_cpu_supports(zend_cpu_feature feature);
98102

99-
#ifdef PHP_HAVE_BUILTIN_CPU_SUPPORTS
103+
#if PHP_HAVE_BUILTIN_CPU_SUPPORTS
100104
/* NOTE: you should use following inline function in
101105
* resolver functions (ifunc), as it could be called
102106
* before all PLT symbols are resloved. in other words,
103107
* resolver functions should not depends any external
104108
* functions */
105109
static zend_always_inline int zend_cpu_support_sse2() {
110+
#if PHP_HAVE_BUILTIN_CPU_INIT
106111
__builtin_cpu_init();
112+
#endif
107113
return __builtin_cpu_supports("sse2");
108114
}
109115

110116
static zend_always_inline int zend_cpu_support_sse3() {
117+
#if PHP_HAVE_BUILTIN_CPU_INIT
111118
__builtin_cpu_init();
119+
#endif
112120
return __builtin_cpu_supports("sse3");
113121
}
114122

115123
static zend_always_inline int zend_cpu_support_sse41() {
124+
#if PHP_HAVE_BUILTIN_CPU_INIT
116125
__builtin_cpu_init();
126+
#endif
117127
return __builtin_cpu_supports("sse4.1");
118128
}
119129

120130
static zend_always_inline int zend_cpu_support_sse42() {
131+
#if PHP_HAVE_BUILTIN_CPU_INIT
121132
__builtin_cpu_init();
133+
#endif
122134
return __builtin_cpu_supports("sse4.2");
123135
}
124136

125137
static zend_always_inline int zend_cpu_support_avx() {
138+
#if PHP_HAVE_BUILTIN_CPU_INIT
126139
__builtin_cpu_init();
140+
#endif
127141
return __builtin_cpu_supports("avx");
128142
}
129143

130144
static zend_always_inline int zend_cpu_support_avx2() {
145+
#if PHP_HAVE_BUILTIN_CPU_INIT
131146
__builtin_cpu_init();
147+
#endif
132148
return __builtin_cpu_supports("avx2");
133149
}
134150
#else

configure.ac

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,8 @@ dnl Check __builtin_ssubl_overflow
566566
PHP_CHECK_BUILTIN_SSUBL_OVERFLOW
567567
dnl Check __builtin_ssubll_overflow
568568
PHP_CHECK_BUILTIN_SSUBLL_OVERFLOW
569+
dnl Check __builtin_cpu_init
570+
PHP_CHECK_BUILTIN_CPU_INIT
569571
dnl Check __builtin_cpu_supports
570572
PHP_CHECK_BUILTIN_CPU_SUPPORTS
571573

0 commit comments

Comments
 (0)