]> granicus.if.org Git - php/commitdiff
Fixed cpu feature check in reslover functions
authorXinchen Hui <laruence@gmail.com>
Sat, 10 Feb 2018 08:58:27 +0000 (16:58 +0800)
committerXinchen Hui <laruence@gmail.com>
Sat, 10 Feb 2018 08:58:27 +0000 (16:58 +0800)
Zend/zend.c
Zend/zend_cpuinfo.c
Zend/zend_cpuinfo.h
acinclude.m4
configure.ac
ext/standard/string.c

index aae1d13b1190d01a7898f819ab9857422324a247..dc0cab8cc02670b0c3fd8beffbbefdbd8e77328b 100644 (file)
@@ -742,9 +742,7 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions) /
        extern zend_php_scanner_globals language_scanner_globals;
 #endif
 
-#ifndef HAVE_FUNC_ATTRIBUTE_IFUNC
        zend_cpu_startup();
-#endif
 
 #ifdef ZEND_WIN32
        php_win32_cp_set_by_id(65001);
index 2b087afaefb88ffdaaadc49fdba6c2ea34e83df0..988ceb252199fa7d958fa2aecb6cef997bd93117 100644 (file)
@@ -16,7 +16,6 @@
    +----------------------------------------------------------------------+
 */
 
-#include "zend.h"
 #include "zend_cpuinfo.h"
 
 typedef struct _zend_cpu_info {
@@ -68,10 +67,6 @@ void zend_cpu_startup(void)
 }
 
 ZEND_API int zend_cpu_supports(zend_cpu_feature feature) {
-#ifdef HAVE_FUNC_ATTRIBUTE_IFUNC
-       /* The resolver is invoked before zend_startup(). */
-       zend_cpu_startup();
-#endif
        if (feature & ZEND_CPU_EDX_MASK) {
                return (cpuinfo.edx & (feature & ~ZEND_CPU_EDX_MASK));
        } else {
index 97e33a55ccb242a91980df11bafc850dac5e190f..c077366bd8323f551764eaaf8a8bf161205bab70 100644 (file)
@@ -19,6 +19,8 @@
 #ifndef ZEND_CPU_INFO_H
 #define ZEND_CPU_INFO_H
 
+#include "zend.h"
+
 #define ZEND_CPU_EDX_MASK     (1<<31)
 
 typedef enum _zend_cpu_feature {
@@ -91,9 +93,72 @@ typedef enum _zend_cpu_feature {
        /*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);
 
-void zend_cpu_startup(void);
+#ifdef 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() {
+       __builtin_cpu_init();
+       return __builtin_cpu_supports("sse2");
+}
+
+static zend_always_inline int zend_cpu_support_sse3() {
+       __builtin_cpu_init();
+       return __builtin_cpu_supports("sse3");
+}
+
+static zend_always_inline int zend_cpu_support_sse41() {
+       __builtin_cpu_init();
+       return __builtin_cpu_supports("sse4.1");
+}
+
+static zend_always_inline int zend_cpu_support_sse42() {
+       __builtin_cpu_init();
+       return __builtin_cpu_supports("sse4.2");
+}
+
+static zend_always_inline int zend_cpu_support_avx() {
+       __builtin_cpu_init();
+       return __builtin_cpu_supports("avx");
+}
+
+static zend_always_inline int zend_cpu_support_avx2() {
+       __builtin_cpu_init();
+       return __builtin_cpu_supports("avx2");
+}
+#else
+
+static zend_always_inline int zend_cpu_support_sse2() {
+       return zend_cpu_supports(ZEND_CPU_FEATURE_SSE2);
+}
+
+static zend_always_inline int zend_cpu_support_sse3() {
+       return zend_cpu_supports(ZEND_CPU_FEATURE_SSE3);
+}
+
+static zend_always_inline int zend_cpu_support_sse41() {
+       return zend_cpu_supports(ZEND_CPU_FEATURE_SSE41);
+}
+
+static zend_always_inline int zend_cpu_support_sse42() {
+       return zend_cpu_supports(ZEND_CPU_FEATURE_SSE42);
+}
+
+static zend_always_inline int zend_cpu_support_avx() {
+       return zend_cpu_supports(ZEND_CPU_FEATURE_AVX);
+}
+
+static zend_always_inline int zend_cpu_support_avx2() {
+       /* TODO */
+       return 0;
+}
+
+#endif
 
 #endif
 
index 347404bfaea1fbcf14d791838c6ba6f6152e5e2f..d74b7b02a129dbe77b5331b94953e05ff154d444 100644 (file)
@@ -3241,6 +3241,25 @@ AC_DEFUN([PHP_CHECK_BUILTIN_CPU_INIT], [
 
 ])
 
+dnl PHP_CHECK_BUILTIN_CPU_SUPPORTS
+AC_DEFUN([PHP_CHECK_BUILTIN_CPU_SUPPORTS], [
+  AC_MSG_CHECKING([for __builtin_cpu_supports])
+
+  AC_TRY_LINK(, [
+    return __builtin_cpu_supports("sse2")? 1 : 0;
+  ], [
+    have_builtin_cpu_supports=1
+    AC_MSG_RESULT([yes])
+  ], [
+    have_builtin_cpu_supports=0
+    AC_MSG_RESULT([no])
+  ])
+
+  AC_DEFINE_UNQUOTED([PHP_HAVE_BUILTIN_CPU_SUPPORTS],
+   [$have_builtin_cpu_supports], [Whether the compiler supports __builtin_cpu_supports])
+
+])
+
 dnl Load the AX_CHECK_COMPILE_FLAG macro from the autoconf archive.
 m4_include([build/ax_check_compile_flag.m4])
 
index 7c0d0072546fb900cf77f071874b69b15b310a1a..d9f1e3fe1bf04ac0a1a30bc97574c67344bc5168 100644 (file)
@@ -566,6 +566,8 @@ dnl Check __builtin_ssubl_overflow
 PHP_CHECK_BUILTIN_SSUBL_OVERFLOW
 dnl Check __builtin_ssubll_overflow
 PHP_CHECK_BUILTIN_SSUBLL_OVERFLOW
+dnl Check __builtin_cpu_supports
+PHP_CHECK_BUILTIN_CPU_SUPPORTS
 
 dnl Check for members of the stat structure
 AC_STRUCT_ST_BLKSIZE
index caaee8c1da106756885c342c896626ebe569c547..b90ce49861f332ec53750a3672474cd3ddac606b 100644 (file)
@@ -3873,7 +3873,7 @@ zend_string *php_addslashes_default(zend_string *str, int should_free);
 PHPAPI zend_string *php_addslashes(zend_string *str, int should_free) __attribute__((ifunc("resolve_addslashes")));
 
 static void *resolve_addslashes() {
-       if (zend_cpu_supports(ZEND_CPU_FEATURE_SSE42)) {
+       if (zend_cpu_support_sse42()) {
                return php_addslashes_sse42;
        }
        return  php_addslashes_default;