summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/tools/qstring.cpp16
-rw-r--r--tests/auto/corelib/tools/qstringref/tst_qstringref.cpp48
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) \