summaryrefslogtreecommitdiff
path: root/Zend
diff options
context:
space:
mode:
authorXinchen Hui <laruence@gmail.com>2018-02-10 17:37:38 +0800
committerXinchen Hui <laruence@gmail.com>2018-02-10 17:38:30 +0800
commit08428cf6a77d360b52028d6ddfe1409218e391db (patch)
tree34c4db557c8353f08da3158320baaa75ed8bda0c /Zend
parent7ce72f0cf5c0b5bc458bee90698e19fb417d8b96 (diff)
downloadphp-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.c1
-rw-r--r--Zend/zend_cpuinfo.c29
-rw-r--r--Zend/zend_cpuinfo.h24
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