arm64 implementation for scanning for non-normal chars in strings

This commit is contained in:
2025-05-24 13:34:59 -04:00
parent 493e6aec31
commit bf3fbd638c

View File

@@ -14,6 +14,9 @@
#ifdef __x86_64__ #ifdef __x86_64__
#include <immintrin.h> #include <immintrin.h>
#endif #endif
#ifdef __aarch64__
#include <arm_neon.h>
#endif
#include "musttail.h" #include "musttail.h"
#include "tables.h" #include "tables.h"
@@ -429,8 +432,37 @@ inline WeaselJsonStatus n_string2(Parser3 *self) {
} }
self->buf += 16; 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 #else
#error "port me" while (self->buf != self->bufEnd &&
tables.stringByteMeaning[uint8_t(*self->buf)] == Tables::NORMAL) {
++self->buf;
}
#endif #endif
int len = self->buf - before; int len = self->buf - before;