diff options
-rw-r--r-- | src/corelib/tools/qstring.cpp | 16 | ||||
-rw-r--r-- | tests/auto/corelib/tools/qstringref/tst_qstringref.cpp | 48 |
2 files changed, 59 insertions, 5 deletions
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 7d409708bb..79365b11b1 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -559,11 +559,13 @@ static int ucstrncmp(const QChar *a, const uchar *c, int l) } } - // we'll read uc[offset..offset+7] (16 bytes) and c[offset-8..offset+7] (16 bytes) +# ifdef Q_PROCESSOR_X86_64 + enum { MaxTailLength = 7 }; + // we'll read uc[offset..offset+7] (16 bytes) and c[offset..offset+7] (8 bytes) if (uc + offset + 7 < e) { - // same, but we'll throw away half the data - __m128i chunk = _mm_loadu_si128((__m128i*)(c + offset - 8)); - __m128i secondHalf = _mm_unpackhi_epi8(chunk, nullmask); + // same, but we're using an 8-byte load + __m128i chunk = _mm_cvtsi64_si128(*(long long *)(c + offset)); + __m128i secondHalf = _mm_unpacklo_epi8(chunk, nullmask); __m128i ucdata = _mm_loadu_si128((__m128i*)(uc + offset)); __m128i result = _mm_cmpeq_epi16(secondHalf, ucdata); @@ -577,6 +579,10 @@ static int ucstrncmp(const QChar *a, const uchar *c, int l) // still matched offset += 8; } +# else + // 32-bit, we can't do MOVQ to load 8 bytes + enum { MaxTailLength = 15 }; +# endif // reset uc and c uc += offset; @@ -584,7 +590,7 @@ static int ucstrncmp(const QChar *a, const uchar *c, int l) # ifdef Q_COMPILER_LAMBDA const auto &lambda = [=](int i) { return uc[i] - ushort(c[i]); }; - return UnrollTailLoop<7>::exec(e - uc, 0, lambda, lambda); + return UnrollTailLoop<MaxTailLength>::exec(e - uc, 0, lambda, lambda); # endif #endif diff --git a/tests/auto/corelib/tools/qstringref/tst_qstringref.cpp b/tests/auto/corelib/tools/qstringref/tst_qstringref.cpp index 7bbcee8ab2..342abb7ea8 100644 --- a/tests/auto/corelib/tools/qstringref/tst_qstringref.cpp +++ b/tests/auto/corelib/tools/qstringref/tst_qstringref.cpp @@ -68,6 +68,8 @@ private slots: void isEmpty(); void compare_data(); void compare(); + void compare2_data(); + void compare2(); void operator_eqeq_nullstring(); void toNum(); void toDouble_data(); @@ -792,11 +794,17 @@ void tst_QStringRef::compare_data() QTest::newRow("data3") << QString("abc") << QString("abc") << 0 << 0; QTest::newRow("data4") << QString("abC") << QString("abc") << -1 << 0; QTest::newRow("data5") << QString("abc") << QString("abC") << 1 << 0; + QTest::newRow("data10") << QString("abcdefgh") << QString("abcdefgh") << 0 << 0; + QTest::newRow("data11") << QString("abcdefgh") << QString("abCdefgh") << 1 << 0; + QTest::newRow("data12") << QString("0123456789012345") << QString("0123456789012345") << 0 << 0; + QTest::newRow("data13") << QString("0123556789012345") << QString("0123456789012345") << 1 << 1; // different length QTest::newRow("data6") << QString("abcdef") << QString("abc") << 1 << 1; QTest::newRow("data7") << QString("abCdef") << QString("abc") << -1 << 1; QTest::newRow("data8") << QString("abc") << QString("abcdef") << -1 << -1; + QTest::newRow("data14") << QString("abcdefgh") << QString("abcdefghi") << -1 << -1; + QTest::newRow("data15") << QString("01234567890123456") << QString("0123456789012345") << 1 << 1; QString upper; upper += QChar(QChar::highSurrogate(0x10400)); @@ -862,6 +870,46 @@ void tst_QStringRef::compare() } } +void tst_QStringRef::compare2_data() +{ + compare_data(); +} + +void tst_QStringRef::compare2() +{ + QFETCH(QString, s1); + QFETCH(QString, s2); + QFETCH(int, csr); + QFETCH(int, cir); + + // prepend and append data + // we only use Latin1 here so isLatin1 still results true + s1.prepend("xyz").append("zyx"); + s2.prepend("foobar").append("raboof"); + + QStringRef r1(&s1, 3, s1.length() - 6); + QStringRef r2(&s2, 6, s2.length() - 12); + + QCOMPARE(sign(QStringRef::compare(r1, r2)), csr); + QCOMPARE(sign(r1.compare(r2)), csr); + + QCOMPARE(sign(r1.compare(r2, Qt::CaseSensitive)), csr); + QCOMPARE(sign(r1.compare(r2, Qt::CaseInsensitive)), cir); + + QCOMPARE(sign(QStringRef::compare(r1, r2, Qt::CaseSensitive)), csr); + QCOMPARE(sign(QStringRef::compare(r1, r2, Qt::CaseInsensitive)), cir); + + if (isLatin(s2)) { + QCOMPARE(sign(QStringRef::compare(r1, QLatin1String(r2.toLatin1()))), csr); + QCOMPARE(sign(QStringRef::compare(r1, QLatin1String(r2.toLatin1()), Qt::CaseInsensitive)), cir); + } + + if (isLatin(s1)) { + QCOMPARE(sign(QStringRef::compare(r2, QLatin1String(r1.toLatin1()))), -csr); + QCOMPARE(sign(QStringRef::compare(r2, QLatin1String(r1.toLatin1()), Qt::CaseInsensitive)), -cir); + } +} + void tst_QStringRef::toNum() { #define TEST_TO_INT(num, func, type) \ |