mirror of https://github.com/qt/qtbase.git
Speculative fix for building on INTEGRITY with ARM NEON
Avoid using inline assembler Task-number: QTBUG-72716 Change-Id: I696efb5a787416eb4fc5ba3a250461aaa9a4afc2 Reviewed-by: Janne Koskinen <janne.p.koskinen@qt.io>
This commit is contained in:
parent
1a707be8b4
commit
ff8d9ad5bc
|
@ -17,8 +17,8 @@ os_directory = $$(INTEGRITY_DIR)
|
||||||
isEmpty(os_directory): \
|
isEmpty(os_directory): \
|
||||||
error("This qmakespec requires $INTEGRITY_DIR to be set")
|
error("This qmakespec requires $INTEGRITY_DIR to be set")
|
||||||
|
|
||||||
QMAKE_CC = cxintarm64 -U__ARM_NEON__ -U__ARM_NEON -bsp $$bsp_name -os_dir $$os_directory -non_shared
|
QMAKE_CC = cxintarm64 -bsp $$bsp_name -os_dir $$os_directory -non_shared
|
||||||
QMAKE_CXX = cxintarm64 -U__ARM_NEON__ -U__ARM_NEON -bsp $$bsp_name -os_dir $$os_directory -non_shared
|
QMAKE_CXX = cxintarm64 -bsp $$bsp_name -os_dir $$os_directory -non_shared
|
||||||
QMAKE_LINK = $$QMAKE_CXX
|
QMAKE_LINK = $$QMAKE_CXX
|
||||||
QMAKE_AR = $$QMAKE_CXX -archive -o
|
QMAKE_AR = $$QMAKE_CXX -archive -o
|
||||||
|
|
||||||
|
|
|
@ -52,65 +52,41 @@ Q_GUI_EXPORT void QT_FASTCALL qt_convert_rgb888_to_rgb32_neon(quint32 *dst, cons
|
||||||
|
|
||||||
const quint32 *const end = dst + len;
|
const quint32 *const end = dst + len;
|
||||||
|
|
||||||
// align dst on 64 bits
|
// align dst on 128 bits
|
||||||
const int offsetToAlignOn8Bytes = (reinterpret_cast<quintptr>(dst) >> 2) & 0x1;
|
const int offsetToAlignOn16Bytes = (reinterpret_cast<quintptr>(dst) >> 2) & 0x3;
|
||||||
for (int i = 0; i < offsetToAlignOn8Bytes; ++i) {
|
for (int i = 0; i < offsetToAlignOn16Bytes; ++i) {
|
||||||
*dst++ = qRgb(src[0], src[1], src[2]);
|
*dst++ = qRgb(src[0], src[1], src[2]);
|
||||||
src += 3;
|
src += 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((len - offsetToAlignOn8Bytes) >= 8) {
|
if ((len - offsetToAlignOn16Bytes) >= 16) {
|
||||||
const quint32 *const simdEnd = end - 7;
|
const quint32 *const simdEnd = end - 15;
|
||||||
#if !defined(Q_PROCESSOR_ARM_64)
|
uint8x16x4_t dstVector;
|
||||||
register uint8x8_t fullVector asm ("d3") = vdup_n_u8(0xff);
|
|
||||||
do {
|
|
||||||
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
|
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
|
||||||
asm volatile (
|
dstVector.val[0] = vdupq_n_u8(0xff);
|
||||||
"vld3.8 { d4, d5, d6 }, [%[SRC]] !\n\t"
|
|
||||||
"vst4.8 { d3, d4, d5, d6 }, [%[DST],:64] !\n\t"
|
|
||||||
: [DST]"+r" (dst), [SRC]"+r" (src)
|
|
||||||
: "w"(fullVector)
|
|
||||||
: "memory", "d4", "d5", "d6"
|
|
||||||
);
|
|
||||||
#else
|
#else
|
||||||
asm volatile (
|
dstVector.val[3] = vdupq_n_u8(0xff);
|
||||||
"vld3.8 { d0, d1, d2 }, [%[SRC]] !\n\t"
|
|
||||||
"vswp d0, d2\n\t"
|
|
||||||
"vst4.8 { d0, d1, d2, d3 }, [%[DST],:64] !\n\t"
|
|
||||||
: [DST]"+r" (dst), [SRC]"+r" (src)
|
|
||||||
: "w"(fullVector)
|
|
||||||
: "memory", "d0", "d1", "d2"
|
|
||||||
);
|
|
||||||
#endif
|
#endif
|
||||||
} while (dst < simdEnd);
|
|
||||||
#else
|
|
||||||
register uint8x8_t fullVector asm ("v3") = vdup_n_u8(0xff);
|
|
||||||
do {
|
do {
|
||||||
|
uint8x16x3_t srcVector = vld3q_u8(src);
|
||||||
|
src += 3 * 16;
|
||||||
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
|
#if Q_BYTE_ORDER == Q_BIG_ENDIAN
|
||||||
asm volatile (
|
dstVector.val[1] = srcVector.val[0];
|
||||||
"ld3 { v4.8b, v5.8b, v6.8b }, [%[SRC]], #24 \n\t"
|
dstVector.val[2] = srcVector.val[1];
|
||||||
"st4 { v3.8b, v4.8b, v5.8b, v6.8b }, [%[DST]], #32 \n\t"
|
dstVector.val[3] = srcVector.val[2];
|
||||||
: [DST]"+r" (dst), [SRC]"+r" (src)
|
|
||||||
: "w"(fullVector)
|
|
||||||
: "memory", "v4", "v5", "v6"
|
|
||||||
);
|
|
||||||
#else
|
#else
|
||||||
asm volatile (
|
dstVector.val[0] = srcVector.val[2];
|
||||||
"ld3 { v0.8b, v1.8b, v2.8b }, [%[SRC]], #24 \n\t"
|
dstVector.val[1] = srcVector.val[1];
|
||||||
"mov v4.8b, v2.8b\n\t"
|
dstVector.val[2] = srcVector.val[0];
|
||||||
"mov v2.8b, v0.8b\n\t"
|
|
||||||
"mov v0.8b, v4.8b\n\t"
|
|
||||||
"st4 { v0.8b, v1.8b, v2.8b, v3.8b }, [%[DST]], #32 \n\t"
|
|
||||||
: [DST]"+r" (dst), [SRC]"+r" (src)
|
|
||||||
: "w"(fullVector)
|
|
||||||
: "memory", "v0", "v1", "v2", "v4"
|
|
||||||
);
|
|
||||||
#endif
|
#endif
|
||||||
|
vst4q_u8(reinterpret_cast<uint8_t*>(dst), dstVector);
|
||||||
|
dst += 16;
|
||||||
} while (dst < simdEnd);
|
} while (dst < simdEnd);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (dst != end) {
|
int i = 0;
|
||||||
|
int length = end - dst;
|
||||||
|
SIMD_EPILOGUE(i, length, 15) {
|
||||||
*dst++ = qRgb(src[0], src[1], src[2]);
|
*dst++ = qRgb(src[0], src[1], src[2]);
|
||||||
src += 3;
|
src += 3;
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,9 +131,11 @@ ARCH_HASWELL_SOURCES += painting/qdrawhelper_avx2.cpp
|
||||||
|
|
||||||
NEON_SOURCES += painting/qdrawhelper_neon.cpp painting/qimagescale_neon.cpp
|
NEON_SOURCES += painting/qdrawhelper_neon.cpp painting/qimagescale_neon.cpp
|
||||||
NEON_HEADERS += painting/qdrawhelper_neon_p.h
|
NEON_HEADERS += painting/qdrawhelper_neon_p.h
|
||||||
NEON_ASM += ../3rdparty/pixman/pixman-arm-neon-asm.S painting/qdrawhelper_neon_asm.S
|
|
||||||
!uikit:!win32:contains(QT_ARCH, "arm"): CONFIG += no_clang_integrated_as
|
!uikit:!win32:contains(QT_ARCH, "arm"): CONFIG += no_clang_integrated_as
|
||||||
!uikit:!win32:!contains(QT_ARCH, "arm64"): DEFINES += ENABLE_PIXMAN_DRAWHELPERS
|
!uikit:!win32:!integrity:!contains(QT_ARCH, "arm64") {
|
||||||
|
NEON_ASM += ../3rdparty/pixman/pixman-arm-neon-asm.S painting/qdrawhelper_neon_asm.S
|
||||||
|
DEFINES += ENABLE_PIXMAN_DRAWHELPERS
|
||||||
|
}
|
||||||
|
|
||||||
MIPS_DSP_SOURCES += painting/qdrawhelper_mips_dsp.cpp
|
MIPS_DSP_SOURCES += painting/qdrawhelper_mips_dsp.cpp
|
||||||
MIPS_DSP_HEADERS += painting/qdrawhelper_mips_dsp_p.h painting/qt_mips_asm_dsp_p.h
|
MIPS_DSP_HEADERS += painting/qdrawhelper_mips_dsp_p.h painting/qt_mips_asm_dsp_p.h
|
||||||
|
|
|
@ -50,7 +50,18 @@ QT_BEGIN_NAMESPACE
|
||||||
void qt_memfill32(quint32 *dest, quint32 value, int count)
|
void qt_memfill32(quint32 *dest, quint32 value, int count)
|
||||||
{
|
{
|
||||||
const int epilogueSize = count % 16;
|
const int epilogueSize = count % 16;
|
||||||
#if !defined(Q_PROCESSOR_ARM_64)
|
#if defined(Q_CC_GHS) || defined(Q_CC_MSVC)
|
||||||
|
// inline assembler free version:
|
||||||
|
if (count >= 16) {
|
||||||
|
quint32 *const neonEnd = dest + count - epilogueSize;
|
||||||
|
const uint32x4_t valueVector1 = vdupq_n_u32(value);
|
||||||
|
const uint32x4x4_t valueVector4 = { valueVector1, valueVector1, valueVector1, valueVector1 };
|
||||||
|
do {
|
||||||
|
vst4q_u32(dest, valueVector4);
|
||||||
|
dest += 16;
|
||||||
|
} while (dest != neonEnd);
|
||||||
|
}
|
||||||
|
#elif !defined(Q_PROCESSOR_ARM_64)
|
||||||
if (count >= 16) {
|
if (count >= 16) {
|
||||||
quint32 *const neonEnd = dest + count - epilogueSize;
|
quint32 *const neonEnd = dest + count - epilogueSize;
|
||||||
register uint32x4_t valueVector1 asm ("q0") = vdupq_n_u32(value);
|
register uint32x4_t valueVector1 asm ("q0") = vdupq_n_u32(value);
|
||||||
|
@ -84,20 +95,20 @@ void qt_memfill32(quint32 *dest, quint32 value, int count)
|
||||||
|
|
||||||
switch (epilogueSize)
|
switch (epilogueSize)
|
||||||
{
|
{
|
||||||
case 15: *dest++ = value;
|
case 15: *dest++ = value; Q_FALLTHROUGH();
|
||||||
case 14: *dest++ = value;
|
case 14: *dest++ = value; Q_FALLTHROUGH();
|
||||||
case 13: *dest++ = value;
|
case 13: *dest++ = value; Q_FALLTHROUGH();
|
||||||
case 12: *dest++ = value;
|
case 12: *dest++ = value; Q_FALLTHROUGH();
|
||||||
case 11: *dest++ = value;
|
case 11: *dest++ = value; Q_FALLTHROUGH();
|
||||||
case 10: *dest++ = value;
|
case 10: *dest++ = value; Q_FALLTHROUGH();
|
||||||
case 9: *dest++ = value;
|
case 9: *dest++ = value; Q_FALLTHROUGH();
|
||||||
case 8: *dest++ = value;
|
case 8: *dest++ = value; Q_FALLTHROUGH();
|
||||||
case 7: *dest++ = value;
|
case 7: *dest++ = value; Q_FALLTHROUGH();
|
||||||
case 6: *dest++ = value;
|
case 6: *dest++ = value; Q_FALLTHROUGH();
|
||||||
case 5: *dest++ = value;
|
case 5: *dest++ = value; Q_FALLTHROUGH();
|
||||||
case 4: *dest++ = value;
|
case 4: *dest++ = value; Q_FALLTHROUGH();
|
||||||
case 3: *dest++ = value;
|
case 3: *dest++ = value; Q_FALLTHROUGH();
|
||||||
case 2: *dest++ = value;
|
case 2: *dest++ = value; Q_FALLTHROUGH();
|
||||||
case 1: *dest++ = value;
|
case 1: *dest++ = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue