From c6d85872bcbed47c6f4c1fcc7526d672ac30f235 Mon Sep 17 00:00:00 2001 From: dixyes Date: Wed, 1 Dec 2021 13:13:56 +0800 Subject: [PATCH] Port win32/codepage.c codes for windows arm64 --- win32/codepage.c | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/win32/codepage.c b/win32/codepage.c index 34f775c8aaff1..69b6a44aa9c8a 100644 --- a/win32/codepage.c +++ b/win32/codepage.c @@ -18,7 +18,11 @@ #include "php.h" #include "SAPI.h" -#include +#ifdef _M_ARM64 +# include +#else +# include +#endif // _M_ARM64 #include "win32/console.h" @@ -134,6 +138,18 @@ PW32CP wchar_t *php_win32_cp_conv_ascii_to_w(const char* in, size_t in_len, size } /* Process aligned chunk. */ +#ifdef _M_ARM64 + uint8x16_t ver_err = {0}; + while (end - idx > 15) { + const uint8x16_t block = vld1q_u8((const void*)idx); + ver_err = vorrq_u8(ver_err, block); + idx += 16; + } + ver_err = vshrq_n_u8(ver_err, 7); + if (vmaxvq_u8(ver_err)) { + ASCII_FAIL_RETURN() + } +#else __m128i vec_err = _mm_setzero_si128(); while (end - idx > 15) { const __m128i block = _mm_load_si128((__m128i *)idx); @@ -143,6 +159,7 @@ PW32CP wchar_t *php_win32_cp_conv_ascii_to_w(const char* in, size_t in_len, size if (_mm_movemask_epi8(vec_err)) { ASCII_FAIL_RETURN() } +#endif // _M_ARM64 } /* Process the trailing part, or otherwise process string < 16 bytes. */ @@ -173,6 +190,22 @@ PW32CP wchar_t *php_win32_cp_conv_ascii_to_w(const char* in, size_t in_len, size /* Process aligned chunk. */ if (end - idx > 15) { +#ifdef _M_ARM64 + while (end - idx > 15) { + /* + vst2q_u8 below will store interlaced vector by 8bits, so this will be little endian wchar + at wrote time all windows arm64 is little endian + */ + uint8x16x2_t vec = {/* .val = */{ + vld1q_u8((const void*)idx), + {0}, + }}; + + vst2q_u8((void*)ret_idx, vec); + idx += 16; + ret_idx += 16; + } +#else const __m128i mask = _mm_set1_epi32(0); while (end - idx > 15) { const __m128i block = _mm_load_si128((__m128i *)idx); @@ -187,6 +220,7 @@ PW32CP wchar_t *php_win32_cp_conv_ascii_to_w(const char* in, size_t in_len, size idx += 16; ret_idx += 8; } +#endif // _M_ARM64 } }