# 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 */
/*
#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)
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);
/* {{{ 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);
}
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
{
/* }}} */
#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)