diff options
author | Benjamin Poulain <benjamin.poulain@nokia.com> | 2010-08-24 04:20:19 +0200 |
---|---|---|
committer | Benjamin Poulain <benjamin.poulain@nokia.com> | 2010-08-25 11:07:12 +0200 |
commit | d28f3ffadec209511d8d992e3b35fae155b3d1c5 (patch) | |
tree | ae6de5aa97c85c05136dff9547bc7089bbe8c7bb /src/gui/painting/qdrawhelper_neon.cpp | |
parent | 9f5457110f86fc11995efd93729c563e0713bebc (diff) |
Implement qt_memfill32 with Neon.
This patch introduce a implementation of qt_memfill32 with the Neon
instructions set from ARMv7.
The loop is unrolled 1 time to get better performance.
This implementation of memfill is 330% faster on the N900.
Reviewed-by: Samuel Rødal
Diffstat (limited to 'src/gui/painting/qdrawhelper_neon.cpp')
-rw-r--r-- | src/gui/painting/qdrawhelper_neon.cpp | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/src/gui/painting/qdrawhelper_neon.cpp b/src/gui/painting/qdrawhelper_neon.cpp index c1f815d636..ed15c5cf8f 100644 --- a/src/gui/painting/qdrawhelper_neon.cpp +++ b/src/gui/painting/qdrawhelper_neon.cpp @@ -51,6 +51,44 @@ QT_BEGIN_NAMESPACE +void qt_memfill32_neon(quint32 *dest, quint32 value, int count) +{ + const int epilogueSize = count % 16; + if (count >= 16) { + quint32 *const neonEnd = dest + count - epilogueSize; + register uint32x4_t valueVector1 asm ("q0") = vdupq_n_u32(value); + register uint32x4_t valueVector2 asm ("q1") = valueVector1; + while (dest != neonEnd) { + asm volatile ( + "vst2.32 { d0, d1, d2, d3 }, [%[DST]] !\n\t" + "vst2.32 { d0, d1, d2, d3 }, [%[DST]] !\n\t" + : [DST]"+r" (dest) + : [VALUE1]"w"(valueVector1), [VALUE2]"w"(valueVector2) + : "memory" + ); + } + } + + switch (epilogueSize) + { + case 15: *dest++ = value; + case 14: *dest++ = value; + case 13: *dest++ = value; + case 12: *dest++ = value; + case 11: *dest++ = value; + case 10: *dest++ = value; + case 9: *dest++ = value; + case 8: *dest++ = value; + case 7: *dest++ = value; + case 6: *dest++ = value; + case 5: *dest++ = value; + case 4: *dest++ = value; + case 3: *dest++ = value; + case 2: *dest++ = value; + case 1: *dest++ = value; + } +} + static inline uint16x8_t qvdiv_255_u16(uint16x8_t x, uint16x8_t half) { // result = (x + (x >> 8) + 0x80) >> 8 |