diff --git a/src/parser3.h b/src/parser3.h index 1cf5a22..1c4d324 100644 --- a/src/parser3.h +++ b/src/parser3.h @@ -14,6 +14,9 @@ #ifdef __x86_64__ #include #endif +#ifdef __aarch64__ +#include +#endif #include "musttail.h" #include "tables.h" @@ -429,8 +432,37 @@ inline WeaselJsonStatus n_string2(Parser3 *self) { } self->buf += 16; } +#elif defined(__aarch64__) + for (;;) { + if (self->bufEnd - self->buf < 16) [[unlikely]] { + while (self->buf != self->bufEnd && + tables.stringByteMeaning[uint8_t(*self->buf)] == Tables::NORMAL) { + ++self->buf; + } + break; + } + uint8x16_t x; + memcpy(&x, self->buf, 16); + const auto dubquote = vceqq_s8(vdupq_n_u8('"'), x); + const auto backslash = vceqq_s8(vdupq_n_u8('\\'), x); + const auto control_or_negative = vcgtq_s8(vdupq_n_u8(0x20), x); + const auto non_normal = vget_lane_u64( + vreinterpret_u64_u16(vshrn_n_u16( + vreinterpretq_u16_u8( + vorrq_s8(vorrq_s8(dubquote, backslash), control_or_negative)), + 4)), + 0); + if (non_normal) { + self->buf += std::countr_zero(non_normal) / 4; + break; + } + self->buf += 16; + } #else -#error "port me" + while (self->buf != self->bufEnd && + tables.stringByteMeaning[uint8_t(*self->buf)] == Tables::NORMAL) { + ++self->buf; + } #endif int len = self->buf - before;