From 5ca5b36b6c8924005129ae5eee61e2445d005f0a Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 3 Oct 2024 22:01:19 -0700 Subject: [PATCH] QUtf8: store even mojibake in simdDecodeAscii() Like we do in simdEncodeAscii(), because there's a good chance it starts with a sequence of ASCII-only content and thus saves us the trouble of processing up to 15 characters in scalar code. Change-Id: I37f4aab92036daf1cec7fffdc2313dfa19f6d2fd Reviewed-by: Allan Sandfeld Jensen --- src/corelib/text/qstringconverter.cpp | 52 +++++++++++---------------- 1 file changed, 20 insertions(+), 32 deletions(-) diff --git a/src/corelib/text/qstringconverter.cpp b/src/corelib/text/qstringconverter.cpp index 02021cb583e..d0d5fdc2fb5 100644 --- a/src/corelib/text/qstringconverter.cpp +++ b/src/corelib/text/qstringconverter.cpp @@ -143,50 +143,38 @@ static inline bool simdDecodeAscii(char16_t *&dst, const uchar *&nextAscii, cons #ifdef __AVX2__ // load and zero extend to an YMM register const __m256i extended = _mm256_cvtepu8_epi16(data); - if (!n) { - // store - _mm256_storeu_si256((__m256i*)dst, extended); - continue; - } + + // store everything, even mojibake + _mm256_storeu_si256((__m256i*)dst, extended); #else - if (!n) { - // unpack - _mm_storeu_si128((__m128i*)dst, _mm_unpacklo_epi8(data, _mm_setzero_si128())); - _mm_storeu_si128(1+(__m128i*)dst, _mm_unpackhi_epi8(data, _mm_setzero_si128())); - continue; - } + // store everything, even mojibake + _mm_storeu_si128((__m128i*)dst, _mm_unpacklo_epi8(data, _mm_setzero_si128())); + _mm_storeu_si128(1+(__m128i*)dst, _mm_unpackhi_epi8(data, _mm_setzero_si128())); #endif - - // copy the front part that is still ASCII - while (!(n & 1)) { - *dst++ = *src++; - n >>= 1; - } - // find the next probable ASCII character // we don't want to load 16 bytes again in this loop if we know there are non-ASCII // characters still coming - n = qBitScanReverse(n); - nextAscii = src + n + 1; - return false; - + if (n) { + uint c = qCountTrailingZeroBits(n); + n = qBitScanReverse(n); + nextAscii = src + n + 1; + src += c; + dst += c; + } + return src == end; } if (end - src >= 8) { __m128i data = _mm_loadl_epi64(reinterpret_cast(src)); uint n = _mm_movemask_epi8(data) & 0xff; - if (!n) { - // unpack and store - _mm_storeu_si128(reinterpret_cast<__m128i *>(dst), _mm_unpacklo_epi8(data, _mm_setzero_si128())); - } else { - while (!(n & 1)) { - *dst++ = *src++; - n >>= 1; - } - + // store everything, even mojibake + _mm_storeu_si128(reinterpret_cast<__m128i *>(dst), _mm_unpacklo_epi8(data, _mm_setzero_si128())); + if (n) { + uint c = qCountTrailingZeroBits(n); n = qBitScanReverse(n); nextAscii = src + n + 1; - return false; + src += c; + dst += c; } }