summaryrefslogtreecommitdiffstats
path: root/src/corelib/codecs
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2018-05-09 20:49:04 -0700
committerThiago Macieira <thiago.macieira@intel.com>2018-05-15 23:04:56 +0000
commit40ccf9818829d4b7df0e4e93a84a25cd75a3f678 (patch)
treee88ea252e2e40e7f824204a5fa2f2f3f2164a2e2 /src/corelib/codecs
parent9d0907b07606ab4da16ae67aac9523fce7ff9525 (diff)
QUtf8: add AVX2 code for isValidUtf8
Change-Id: I5d0ee9389a794d80983efffd152d2beca86c5779 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'src/corelib/codecs')
-rw-r--r--src/corelib/codecs/qutfcodec.cpp22
1 files changed, 22 insertions, 0 deletions
diff --git a/src/corelib/codecs/qutfcodec.cpp b/src/corelib/codecs/qutfcodec.cpp
index ce1b092a54..08cc99f4dc 100644
--- a/src/corelib/codecs/qutfcodec.cpp
+++ b/src/corelib/codecs/qutfcodec.cpp
@@ -155,6 +155,28 @@ static inline bool simdDecodeAscii(ushort *&dst, const uchar *&nextAscii, const
static inline const uchar *simdFindNonAscii(const uchar *src, const uchar *end, const uchar *&nextAscii)
{
+#ifdef __AVX2__
+ // do 32 characters at a time
+ // (this is similar to simdTestMask in qstring.cpp)
+ const __m256i mask = _mm256_set1_epi8(0x80);
+ for ( ; end - src >= 32; src += 32) {
+ __m256i data = _mm256_loadu_si256(reinterpret_cast<const __m256i *>(src));
+ if (_mm256_testz_si256(mask, data))
+ continue;
+
+ uint n = _mm256_movemask_epi8(data);
+ Q_ASSUME(n);
+
+ // find the next probable ASCII character
+ // we don't want to load 32 bytes again in this loop if we know there are non-ASCII
+ // characters still coming
+ nextAscii = src + qBitScanReverse(n) + 1;
+
+ // return the non-ASCII character
+ return src + qCountTrailingZeroBits(n);
+ }
+#endif
+
// do sixteen characters at a time
for ( ; end - src >= 16; src += 16) {
__m128i data = _mm_loadu_si128(reinterpret_cast<const __m128i*>(src));