// Glaze Library // For the license information refer to glaze.hpp #pragma once #include "glaze/simd/simd.hpp" #include "glaze/util/bit.hpp" #include "glaze/util/inline.hpp" #if defined(GLZ_USE_SSE2) namespace glz::detail { template GLZ_ALWAYS_INLINE void sse2_string_escape(const char*& c, const char* e, Data*& data, size_t n, WriteEscape&& write_escape) { // SSE2: 16 bytes at a time with direct comparison instructions if (n > 15) { const __m128i quote_vec = _mm_set1_epi8('"'); const __m128i bs_vec = _mm_set1_epi8('\\'); const __m128i ctrl_mask = _mm_set1_epi8(static_cast(0xE0)); const __m128i zero = _mm_setzero_si128(); for (const char* end_m15 = e - 15; c < end_m15;) { __m128i v = _mm_loadu_si128(reinterpret_cast(c)); _mm_storeu_si128(reinterpret_cast<__m128i*>(data), v); const uint32_t mask = static_cast( _mm_movemask_epi8(_mm_or_si128(_mm_or_si128(_mm_cmpeq_epi8(v, quote_vec), _mm_cmpeq_epi8(v, bs_vec)), _mm_cmpeq_epi8(_mm_and_si128(v, ctrl_mask), zero)))); if (mask == 0) { data += 16; c += 16; continue; } const uint32_t length = countr_zero(mask); c += length; data += length; write_escape(); } } } } #endif