From 396ca141fd737f96744210eedc81573a93f3d26b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E6=9D=A8=E5=B8=86?= <39647285+leno23@users.noreply.github.com> Date: Tue, 19 May 2026 05:13:43 +0800 Subject: [PATCH] perf(builder): add LSX fast_needs_escaping for LoongArch (#2727) Use LSX intrinsics for the string-builder escape scan on LoongArch, matching the existing find_next_json_quotable_character LSX path. Fixes #2603 --- .../generic/builder/json_string_builder-inl.h | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/include/simdjson/generic/builder/json_string_builder-inl.h b/include/simdjson/generic/builder/json_string_builder-inl.h index 7a63c7480..7f149f2b7 100644 --- a/include/simdjson/generic/builder/json_string_builder-inl.h +++ b/include/simdjson/generic/builder/json_string_builder-inl.h @@ -173,6 +173,35 @@ simdjson_inline bool fast_needs_escaping(std::string_view view) { } return _mm_movemask_epi8(running) != 0; } +#elif SIMDJSON_EXPERIMENTAL_HAS_LSX +simdjson_inline bool fast_needs_escaping(std::string_view view) { + if (view.size() < 16) { + return simple_needs_escaping(view); + } + size_t i = 0; + __m128i running = __lsx_vreplgr2vr_b(0); + __m128i v34 = __lsx_vreplgr2vr_b(34); + __m128i v92 = __lsx_vreplgr2vr_b(92); + __m128i v32 = __lsx_vreplgr2vr_b(32); + + for (; i + 15 < view.size(); i += 16) { + __m128i word = + __lsx_vld(reinterpret_cast(view.data() + i), 0); + __m128i chunk = __lsx_vseq_b(word, v34); + chunk = __lsx_vor_v(chunk, __lsx_vseq_b(word, v92)); + chunk = __lsx_vor_v(chunk, __lsx_vslt_bu(word, v32)); + running = __lsx_vor_v(running, chunk); + } + if (i < view.size()) { + __m128i word = __lsx_vld( + reinterpret_cast(view.data() + view.length() - 16), 0); + __m128i chunk = __lsx_vseq_b(word, v34); + chunk = __lsx_vor_v(chunk, __lsx_vseq_b(word, v92)); + chunk = __lsx_vor_v(chunk, __lsx_vslt_bu(word, v32)); + running = __lsx_vor_v(running, chunk); + } + return !__lsx_bz_v(running); +} #elif SIMDJSON_EXPERIMENTAL_HAS_PPC64 simdjson_inline bool fast_needs_escaping(std::string_view view) { if (view.size() < 16) {