]> granicus.if.org Git - php/commitdiff
Implement intrinsic function resolving per MINIT
authorAnatol Belski <ab@php.net>
Wed, 24 Jan 2018 08:33:32 +0000 (09:33 +0100)
committerAnatol Belski <ab@php.net>
Wed, 24 Jan 2018 08:33:32 +0000 (09:33 +0100)
Zend/zend_portability.h
ext/standard/basic_functions.c
ext/standard/php_string.h
ext/standard/string.c

index ba4cbb2938ffb0f6a742c70956694a4449225cc5..92b9bb307e5b39331c0a0d18a852fec3fb305221 100644 (file)
@@ -514,6 +514,24 @@ static zend_always_inline double _zend_get_nan(void) /* {{{ */
 # endif
 #endif
 
+#if defined(__GNUC__) && defined(HAVE_FUNC_ATTRIBUTE_IFUNC) && defined(HAVE_FUNC_ATTRIBUTE_TARGET)
+# define ZEND_INTRIN_HAVE_IFUNC_TARGET 1
+#endif
+
+#if defined(__GNUC__) && defined(__SSE4_2__)
+/* Instructions compiled directly. */
+# define ZEND_INTRIN_SSE4_2_NATIVE 1
+#elif (defined(__i386__) || defined(__x86_64__)) && defined(HAVE_NMMINTRIN_H) || defined(PHP_WIN32)
+/* Function resolved by ifunc or MINIT. */
+# define ZEND_INTRIN_SSE4_2_RESOLVER 1
+#endif
+
+#if ZEND_INTRIN_HAVE_IFUNC_TARGET && (ZEND_INTRIN_SSE4_2_NATIVE || ZEND_INTRIN_SSE4_2_RESOLVER)
+# define ZEND_INTRIN_SSE4_2_FUNC_PROTO 1
+#elif ZEND_INTRIN_SSE4_2_RESOLVER
+# define ZEND_INTRIN_SSE4_2_FUNC_PTR 1
+#endif
+
 #endif /* ZEND_PORTABILITY_H */
 
 /*
index 60dbf1391cef4e1ed6299af78dc892a0fe25bbf6..b322caa65e3790614b9e0804894ff1c479df1fa5 100644 (file)
@@ -3688,6 +3688,10 @@ PHP_MINIT_FUNCTION(basic) /* {{{ */
        BASIC_MINIT_SUBMODULE(nl_langinfo)
 #endif
 
+#if ZEND_INTRIN_SSE4_2_FUNC_PTR
+       BASIC_MINIT_SUBMODULE(string_intrin)
+#endif
+
        BASIC_MINIT_SUBMODULE(crypt)
        BASIC_MINIT_SUBMODULE(lcg)
 
index bce155f6da344749b53180f049a90bc1f0c7c020..6e3642c4acbea7d1e98fccea0c381614eeaa2e35 100644 (file)
@@ -109,6 +109,9 @@ PHP_MSHUTDOWN_FUNCTION(localeconv);
 #if HAVE_NL_LANGINFO
 PHP_MINIT_FUNCTION(nl_langinfo);
 #endif
+#if ZEND_INTRIN_SSE4_2_FUNC_PTR
+PHP_MINIT_FUNCTION(string_intrin);
+#endif
 
 #define strnatcmp(a, b) \
        strnatcmp_ex(a, strlen(a), b, strlen(b), 0)
@@ -125,7 +128,11 @@ PHPAPI char *php_strtolower(char *s, size_t len);
 PHPAPI zend_string *php_string_toupper(zend_string *s);
 PHPAPI zend_string *php_string_tolower(zend_string *s);
 PHPAPI char *php_strtr(char *str, size_t len, const char *str_from, const char *str_to, size_t trlen);
+#if ZEND_INTRIN_SSE4_2_FUNC_PTR
+PHPAPI extern zend_string *(*php_addslashes)(zend_string *str, int should_free);
+#else
 PHPAPI zend_string *php_addslashes(zend_string *str, int should_free);
+#endif
 PHPAPI zend_string *php_addcslashes(zend_string *str, int freeit, char *what, size_t what_len);
 PHPAPI void php_stripslashes(zend_string *str);
 PHPAPI void php_stripcslashes(zend_string *str);
index 1e615698a2af7b91f9aa728ce6fd6bc8519a1c77..8915c532a46405084de42c7ce8a3ccde3e11b58e 100644 (file)
@@ -3866,17 +3866,15 @@ PHPAPI zend_string *php_addcslashes(zend_string *str, int should_free, char *wha
 
 /* {{{ php_addslashes */
 
-#if defined(__GNUC__) && defined(__SSE4_2__)
+#if ZEND_INTRIN_SSE4_2_NATIVE
 # include <nmmintrin.h>
 # include "Zend/zend_bitset.h"
-# define PHP_ADDSLASHES_LEVEL 2
-#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && \
-      defined(HAVE_FUNC_ATTRIBUTE_IFUNC) && defined(HAVE_FUNC_ATTRIBUTE_TARGET) && defined(HAVE_NMMINTRIN_H)
+#elif ZEND_INTRIN_SSE4_2_RESOLVER
 # include <nmmintrin.h>
 # include "Zend/zend_bitset.h"
 # include "Zend/zend_cpuinfo.h"
-# define PHP_ADDSLASHES_LEVEL 1
 
+# if ZEND_INTRIN_SSE4_2_FUNC_PROTO
 PHPAPI zend_string *php_addslashes(zend_string *str, int should_free) __attribute__((ifunc("resolve_addslashes")));
 zend_string *php_addslashes_sse42(zend_string *str, int should_free) __attribute__((target("sse4.2")));
 zend_string *php_addslashes_default(zend_string *str, int should_free);
@@ -3887,14 +3885,31 @@ static void *resolve_addslashes() {
        }
        return  php_addslashes_default;
 }
-#else
-# define PHP_ADDSLASHES_LEVEL 0
+# else /* ZEND_INTRIN_SSE4_2_FUNC_PTR */
+zend_string *php_addslashes_sse42(zend_string *str, int should_free);
+zend_string *php_addslashes_default(zend_string *str, int should_free);
+
+PHPAPI zend_string *(*php_addslashes)(zend_string *str, int should_free) = NULL;
+
+/* {{{ PHP_MINIT_FUNCTION
+ */
+PHP_MINIT_FUNCTION(string_intrin)
+{
+       if (zend_cpu_supports(ZEND_CPU_FEATURE_SSE42)) {
+               php_addslashes = php_addslashes_sse42;
+       } else {
+               php_addslashes = php_addslashes_default;
+       }
+       return SUCCESS;
+}
+/* }}} */
+# endif
 #endif
 
-#if PHP_ADDSLASHES_LEVEL
-# if PHP_ADDSLASHES_LEVEL == 2
+#if ZEND_INTRIN_SSE4_2_NATIVE || ZEND_INTRIN_SSE4_2_RESOLVER
+# if ZEND_INTRIN_SSE4_2_NATIVE
 PHPAPI zend_string *php_addslashes(zend_string *str, int should_free) /* {{{ */
-# else
+# elif ZEND_INTRIN_SSE4_2_RESOLVER
 zend_string *php_addslashes_sse42(zend_string *str, int should_free)
 # endif
 {
@@ -4078,8 +4093,8 @@ do_escape:
 /* }}} */
 #endif
 
-#if PHP_ADDSLASHES_LEVEL != 2
-# if PHP_ADDSLASHES_LEVEL == 1
+#if !ZEND_INTRIN_SSE4_2_NATIVE
+# if ZEND_INTRIN_SSE4_2_RESOLVER
 zend_string *php_addslashes_default(zend_string *str, int should_free) /* {{{ */
 # else
 PHPAPI zend_string *php_addslashes(zend_string *str, int should_free)