summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@qt.io>2016-10-07 12:14:58 +0200
committerErik Verbruggen <erik.verbruggen@qt.io>2016-11-11 11:55:56 +0000
commitc877af847a588f958c1c7ed31ef138d44e6a9507 (patch)
tree7cedca2df6598736d94bb994cbe04a0f69535d69 /src/corelib
parent6ad1012758af5af7d6313c3e76abb9c06e35547f (diff)
Aarch64: Vectorize ucstrncmp of QChar arrays
Change-Id: I0b3f9d975bfdf6839b97f5753f299074dbf8face Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/tools/qstring.cpp24
1 files changed, 24 insertions, 0 deletions
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index 3689e5aaeb..c6af05c73e 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -491,6 +491,30 @@ static int ucstrncmp(const QChar *a, const QChar *b, int l)
return UnrollTailLoop<7>::exec(l, 0, lambda, lambda);
# endif
#endif
+#if defined(__ARM_NEON__) && defined(Q_PROCESSOR_ARM_64) // vaddv is only available on Aarch64
+ if (l >= 8) {
+ const QChar *end = a + l;
+ const uint16x8_t mask = { 1, 1 << 1, 1 << 2, 1 << 3, 1 << 4, 1 << 5, 1 << 6, 1 << 7 };
+ while (a + 8 < end) {
+ uint16x8_t da = vld1q_u16(reinterpret_cast<const uint16_t *>(a));
+ uint16x8_t db = vld1q_u16(reinterpret_cast<const uint16_t *>(b));
+
+ uint8_t r = ~(uint8_t)vaddvq_u16(vandq_u16(vceqq_u16(da, db), mask));
+ if (r) {
+ // found a different QChar
+ uint idx = qCountTrailingZeroBits(r);
+ return (int)a[idx].unicode() - (int)b[idx].unicode();
+ }
+ a += 8;
+ b += 8;
+ }
+ l &= 7;
+ }
+ const auto &lambda = [=](int i) -> int {
+ return a[i].unicode() - b[i].unicode();
+ };
+ return UnrollTailLoop<7>::exec(l, 0, lambda, lambda);
+#endif // __ARM_NEON__
if (!l)
return 0;