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 <allan.jensen@qt.io>
This commit is contained in:
parent
ad31a90319
commit
5ca5b36b6c
@ -143,50 +143,38 @@ static inline bool simdDecodeAscii(char16_t *&dst, const uchar *&nextAscii, cons
|
|||||||
#ifdef __AVX2__
|
#ifdef __AVX2__
|
||||||
// load and zero extend to an YMM register
|
// load and zero extend to an YMM register
|
||||||
const __m256i extended = _mm256_cvtepu8_epi16(data);
|
const __m256i extended = _mm256_cvtepu8_epi16(data);
|
||||||
if (!n) {
|
|
||||||
// store
|
// store everything, even mojibake
|
||||||
_mm256_storeu_si256((__m256i*)dst, extended);
|
_mm256_storeu_si256((__m256i*)dst, extended);
|
||||||
continue;
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
if (!n) {
|
// store everything, even mojibake
|
||||||
// unpack
|
_mm_storeu_si128((__m128i*)dst, _mm_unpacklo_epi8(data, _mm_setzero_si128()));
|
||||||
_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()));
|
||||||
_mm_storeu_si128(1+(__m128i*)dst, _mm_unpackhi_epi8(data, _mm_setzero_si128()));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// copy the front part that is still ASCII
|
|
||||||
while (!(n & 1)) {
|
|
||||||
*dst++ = *src++;
|
|
||||||
n >>= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// find the next probable ASCII character
|
// 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
|
// we don't want to load 16 bytes again in this loop if we know there are non-ASCII
|
||||||
// characters still coming
|
// characters still coming
|
||||||
n = qBitScanReverse(n);
|
if (n) {
|
||||||
nextAscii = src + n + 1;
|
uint c = qCountTrailingZeroBits(n);
|
||||||
return false;
|
n = qBitScanReverse(n);
|
||||||
|
nextAscii = src + n + 1;
|
||||||
|
src += c;
|
||||||
|
dst += c;
|
||||||
|
}
|
||||||
|
return src == end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (end - src >= 8) {
|
if (end - src >= 8) {
|
||||||
__m128i data = _mm_loadl_epi64(reinterpret_cast<const __m128i *>(src));
|
__m128i data = _mm_loadl_epi64(reinterpret_cast<const __m128i *>(src));
|
||||||
uint n = _mm_movemask_epi8(data) & 0xff;
|
uint n = _mm_movemask_epi8(data) & 0xff;
|
||||||
if (!n) {
|
// store everything, even mojibake
|
||||||
// unpack and store
|
_mm_storeu_si128(reinterpret_cast<__m128i *>(dst), _mm_unpacklo_epi8(data, _mm_setzero_si128()));
|
||||||
_mm_storeu_si128(reinterpret_cast<__m128i *>(dst), _mm_unpacklo_epi8(data, _mm_setzero_si128()));
|
if (n) {
|
||||||
} else {
|
uint c = qCountTrailingZeroBits(n);
|
||||||
while (!(n & 1)) {
|
|
||||||
*dst++ = *src++;
|
|
||||||
n >>= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
n = qBitScanReverse(n);
|
n = qBitScanReverse(n);
|
||||||
nextAscii = src + n + 1;
|
nextAscii = src + n + 1;
|
||||||
return false;
|
src += c;
|
||||||
|
dst += c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user