diff --git a/include/ada/common_defs.h b/include/ada/common_defs.h index 8aacdb56d..675d750dd 100644 --- a/include/ada/common_defs.h +++ b/include/ada/common_defs.h @@ -292,6 +292,10 @@ namespace ada { #define ADA_SSE2 1 #endif +#if defined(__ARM_FEATURE_SVE) +#define ADA_SVE 1 +#endif + #if defined(__aarch64__) || defined(_M_ARM64) #define ADA_NEON 1 #endif diff --git a/src/unicode.cpp b/src/unicode.cpp index e4c4ea827..e363c52fe 100644 --- a/src/unicode.cpp +++ b/src/unicode.cpp @@ -8,7 +8,9 @@ ADA_PUSH_DISABLE_ALL_WARNINGS ADA_POP_DISABLE_WARNINGS #include -#if ADA_NEON +#if ADA_SVE +#include +#elif ADA_NEON #include #elif ADA_SSE2 #include @@ -44,7 +46,27 @@ constexpr bool to_lower_ascii(char* input, size_t length) noexcept { } return non_ascii == 0; } -#if ADA_NEON +#endif +#if ADA_SVE +ada_really_inline bool has_tabs_or_newline( + std::string_view user_input) noexcept { + const svuint8_t mask1 = svdup_n_u8('\r'); + const svuint8_t mask2 = svdup_n_u8('\n'); + const svuint8_t mask3 = svdup_n_u8('\t'); + svbool_t running = svdup_n_b8(false); + const size_t lanes = svcntb(); + for (size_t i = 0; i < user_input.size(); i += lanes) { + const svbool_t mask = svwhilelt_b8_u64(i, user_input.size()); + svuint8_t word = svld1_u8(mask, (const uint8_t*)user_input.data() + i); + running = svorr_b_z(mask, + svorr_b_z(mask, running, + svorr_b_z(mask, svcmpeq_u8(mask, word, mask1), + svcmpeq_u8(mask, word, mask2))), + svcmpeq_u8(mask, word, mask3)); + } + return svptest_any(running); +} +#elif ADA_NEON ada_really_inline bool has_tabs_or_newline( std::string_view user_input) noexcept { size_t i = 0;