arm64 implementation for scanning for non-normal chars in strings
This commit is contained in:
@@ -14,6 +14,9 @@
|
||||
#ifdef __x86_64__
|
||||
#include <immintrin.h>
|
||||
#endif
|
||||
#ifdef __aarch64__
|
||||
#include <arm_neon.h>
|
||||
#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;
|
||||
|
||||
Reference in New Issue
Block a user