diff options
author | Qt Continuous Integration System <qt-info@nokia.com> | 2011-06-17 08:07:22 (GMT) |
---|---|---|
committer | Qt Continuous Integration System <qt-info@nokia.com> | 2011-06-17 08:07:22 (GMT) |
commit | fd7ba9728a9a580fc446b71134d4c0647c235b4f (patch) | |
tree | e858c4560397844b19586e8dbebb936eebfa9a06 /src/corelib/tools/qstring.cpp | |
parent | 72bd10eed1f15d8ef3c233acb51212f18bc02f35 (diff) | |
parent | f078275a2a4b2a279a6fcc24df3c21fe8b21f007 (diff) | |
download | Qt-fd7ba9728a9a580fc446b71134d4c0647c235b4f.zip Qt-fd7ba9728a9a580fc446b71134d4c0647c235b4f.tar.gz Qt-fd7ba9728a9a580fc446b71134d4c0647c235b4f.tar.bz2 |
Merge branch 'master' of git://scm.dev.nokia.troll.no/qt/qt-releng-team
* 'master' of git://scm.dev.nokia.troll.no/qt/qt-releng-team: (210 commits)
QTBUG-19500 lupdate fails to run from the Mac binary package on Mac OS X 10.5
DEF file updates for Symbian
QTBUG-19883 Adding top level TRAP for QThreads on Symbian
Revert "QFileInfoGatherer: call QFileSystemWatcher addPaths from proper thread"
Fix alignment value not handled in ODF
Silence a compiler warning about unhandled enum in switch
Silence the "array out of bounds" warning in GCC 4.6.
Silence the callgrind warnings in our source code when using gcc 4.6
Create a function that merges the SSE common code
Improve toLatin1 x86 SIMD by using a new SSE4.1 instruction
Revert "Fix compilation of lrelease on Windows"
QFileInfoGatherer: call QFileSystemWatcher addPaths from proper thread
Also test http proxy in the QTcpServer benchmark
Symbian QFileSystemWatcher: fix potential crash
Enable QTcpServer benchmark on symbian
Fix building the OpenVG graphicssystem on Linux with static libs
fix build on windows 7
Fix compilation of lrelease on Windows
Allow selecting fonts with irregular style names
Fix missing empty lines in Qt HTML when displayed in compliant browsers
...
Diffstat (limited to 'src/corelib/tools/qstring.cpp')
-rw-r--r-- | src/corelib/tools/qstring.cpp | 64 |
1 files changed, 35 insertions, 29 deletions
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 8ad4e70..0edf291 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -3556,6 +3556,38 @@ bool QString::endsWith(const QChar &c, Qt::CaseSensitivity cs) const Use toLocal8Bit() instead. */ +#if defined(QT_ALWAYS_HAVE_SSE2) +static inline __m128i mergeQuestionMarks(__m128i chunk) +{ + const __m128i questionMark = _mm_set1_epi16('?'); + + // SSE has no compare instruction for unsigned comparison. + // The variables must be shiffted + 0x8000 to be compared + const __m128i signedBitOffset = _mm_set1_epi16(0x8000); + const __m128i thresholdMask = _mm_set1_epi16(0xff + 0x8000); + + const __m128i signedChunk = _mm_add_epi16(chunk, signedBitOffset); + const __m128i offLimitMask = _mm_cmpgt_epi16(signedChunk, thresholdMask); + +# ifdef __SSE4_1__ + // replace the non-Latin 1 characters in the chunk with question marks + chunk = _mm_blendv_epi8(chunk, questionMark, offLimitMask); +# else + // offLimitQuestionMark contains '?' for each 16 bits that was off-limit + // the 16 bits that were correct contains zeros + const __m128i offLimitQuestionMark = _mm_and_si128(offLimitMask, questionMark); + + // correctBytes contains the bytes that were in limit + // the 16 bits that were off limits contains zeros + const __m128i correctBytes = _mm_andnot_si128(offLimitMask, chunk); + + // merge offLimitQuestionMark and correctBytes to have the result + chunk = _mm_or_si128(correctBytes, offLimitQuestionMark); +# endif + return chunk; +} +#endif + static QByteArray toLatin1_helper(const QChar *data, int length) { QByteArray ba; @@ -3566,41 +3598,15 @@ static QByteArray toLatin1_helper(const QChar *data, int length) #if defined(QT_ALWAYS_HAVE_SSE2) if (length >= 16) { const int chunkCount = length >> 4; // divided by 16 - const __m128i questionMark = _mm_set1_epi16('?'); - // SSE has no compare instruction for unsigned comparison. - // The variables must be shiffted + 0x8000 to be compared - const __m128i signedBitOffset = _mm_set1_epi16(0x8000); - const __m128i thresholdMask = _mm_set1_epi16(0xff + 0x8000); + for (int i = 0; i < chunkCount; ++i) { __m128i chunk1 = _mm_loadu_si128((__m128i*)src); // load + chunk1 = mergeQuestionMarks(chunk1); src += 8; - { - // each 16 bit is equal to 0xFF if the source is outside latin 1 (>0xff) - const __m128i signedChunk = _mm_add_epi16(chunk1, signedBitOffset); - const __m128i offLimitMask = _mm_cmpgt_epi16(signedChunk, thresholdMask); - - // offLimitQuestionMark contains '?' for each 16 bits that was off-limit - // the 16 bits that were correct contains zeros - const __m128i offLimitQuestionMark = _mm_and_si128(offLimitMask, questionMark); - - // correctBytes contains the bytes that were in limit - // the 16 bits that were off limits contains zeros - const __m128i correctBytes = _mm_andnot_si128(offLimitMask, chunk1); - - // merge offLimitQuestionMark and correctBytes to have the result - chunk1 = _mm_or_si128(correctBytes, offLimitQuestionMark); - } __m128i chunk2 = _mm_loadu_si128((__m128i*)src); // load + chunk2 = mergeQuestionMarks(chunk2); src += 8; - { - // exactly the same operations as for the previous chunk of data - const __m128i signedChunk = _mm_add_epi16(chunk2, signedBitOffset); - const __m128i offLimitMask = _mm_cmpgt_epi16(signedChunk, thresholdMask); - const __m128i offLimitQuestionMark = _mm_and_si128(offLimitMask, questionMark); - const __m128i correctBytes = _mm_andnot_si128(offLimitMask, chunk2); - chunk2 = _mm_or_si128(correctBytes, offLimitQuestionMark); - } // pack the two vector to 16 x 8bits elements const __m128i result = _mm_packus_epi16(chunk1, chunk2); |