From 4417458d62d1f75927b9f2e807e8843a49b01aa7 Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Fri, 11 Dec 2015 13:04:46 +0100 Subject: ARMv8: add crc32 feature detection. Change-Id: I3cfac90dfa137d0bf3d124d87262eb2dbb56459c Reviewed-by: Thiago Macieira --- src/corelib/tools/qsimd.cpp | 46 ++++++++++++++++++++++++++++++++++++++++----- src/corelib/tools/qsimd_p.h | 24 +++++++++++++++++++++-- 2 files changed, 63 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/corelib/tools/qsimd.cpp b/src/corelib/tools/qsimd.cpp index 171e87df05..ef4ce741aa 100644 --- a/src/corelib/tools/qsimd.cpp +++ b/src/corelib/tools/qsimd.cpp @@ -65,8 +65,15 @@ #define HWCAP_VFPv3 8192 #define HWCAP_VFPv3D16 16384 +// copied from (ARM): +#define HWCAP2_CRC32 (1 << 4) + +// copied from (Aarch64) +#define HWCAP_CRC32 (1 << 7) + // copied from #define AT_HWCAP 16 /* arch dependent hints at CPU capabilities */ +#define AT_HWCAP2 26 /* extension of AT_HWCAP */ #elif defined(Q_CC_GHS) #include @@ -103,7 +110,16 @@ static inline quint64 detectProcessorFeatures() { quint64 features = 0; -#if defined(Q_OS_LINUX) +#if defined(Q_OS_IOS) + features |= Q_UINT64_C(1) << CpuFeatureNEON; // On iOS, NEON is always available. +# ifdef Q_PROCESSOR_ARM_V8 + features |= Q_UINT64_C(1) << CpuFeatureCRC32; // On iOS, crc32 is always available if the architecture is Aarch32/64. +# endif + return features; +#elif defined(Q_OS_LINUX) +# if defined(Q_PROCESSOR_ARM_V8) && defined(Q_PROCESSOR_ARM_64) + features |= Q_UINT64_C(1) << CpuFeatureNEON; // NEON is always available on ARMv8 64bit. +# endif int auxv = qt_safe_open("/proc/self/auxv", O_RDONLY); if (auxv != -1) { unsigned long vector[64]; @@ -116,12 +132,25 @@ static inline quint64 detectProcessorFeatures() } int max = nread / (sizeof vector[0]); - for (int i = 0; i < max; i += 2) + for (int i = 0; i < max; i += 2) { if (vector[i] == AT_HWCAP) { +# if defined(Q_PROCESSOR_ARM_V8) && defined(Q_PROCESSOR_ARM_64) + // For Aarch64: + if (vector[i+1] & HWCAP_CRC32) + features |= Q_UINT64_C(1) << CpuFeatureCRC32; +# endif + // Aarch32, or ARMv7 or before: if (vector[i+1] & HWCAP_NEON) features |= Q_UINT64_C(1) << CpuFeatureNEON; - break; } +# if defined(Q_PROCESSOR_ARM_32) + // For Aarch32: + if (vector[i] == AT_HWCAP2) { + if (vector[i+1] & HWCAP2_CRC32) + features |= Q_UINT64_C(1) << CpuFeatureCRC32; + } +# endif + } } qt_safe_close(auxv); @@ -133,6 +162,9 @@ static inline quint64 detectProcessorFeatures() #if defined(__ARM_NEON__) features = Q_UINT64_C(1) << CpuFeatureNEON; #endif +#if defined(__ARM_FEATURE_CRC32) + features = Q_UINT64_C(1) << CpuFeatureCRC32; +#endif return features; } @@ -498,9 +530,13 @@ static inline uint detectProcessorFeatures() #if defined(Q_PROCESSOR_ARM) /* Data: neon + crc32 */ -static const char features_string[] = " neon\0"; -static const int features_indices[] = { 0 }; +static const char features_string[] = + " neon\0" + " crc32\0" + "\0"; +static const int features_indices[] = { 0, 6 }; #elif defined(Q_PROCESSOR_MIPS) /* Data: dsp diff --git a/src/corelib/tools/qsimd_p.h b/src/corelib/tools/qsimd_p.h index dedee06e38..7aa5099a32 100644 --- a/src/corelib/tools/qsimd_p.h +++ b/src/corelib/tools/qsimd_p.h @@ -138,7 +138,18 @@ #define QT_COMPILER_SUPPORTS(x) (QT_COMPILER_SUPPORTS_ ## x - 0) -#if (defined(Q_CC_INTEL) || defined(Q_CC_MSVC) \ +#if defined(Q_PROCESSOR_ARM) +# define QT_COMPILER_SUPPORTS_HERE(x) (__ARM_FEATURE_ ## x) +# if defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && Q_CC_GNU >= 600 + /* GCC requires attributes for a function */ +# define QT_FUNCTION_TARGET(x) __attribute__((__target__(QT_FUNCTION_TARGET_STRING_ ## x))) +# else +# define QT_FUNCTION_TARGET(x) +# endif +# if !defined(__ARM_FEATURE_NEON) && defined(__ARM_NEON__) +# define __ARM_FEATURE_NEON // also support QT_COMPILER_SUPPORTS_HERE(NEON) +# endif +#elif (defined(Q_CC_INTEL) || defined(Q_CC_MSVC) \ || (defined(Q_CC_GNU) && !defined(Q_CC_CLANG) && (__GNUC__-0) * 100 + (__GNUC_MINOR__-0) >= 409)) \ && !defined(QT_BOOTSTRAPPED) # define QT_COMPILER_SUPPORTS_SIMD_ALWAYS @@ -253,12 +264,17 @@ // note: as of GCC 4.9, does not support function targets for ARM #if defined(__ARM_NEON) || defined(__ARM_NEON__) #include -#define QT_FUNCTION_TARGET_STRING_ARM_NEON "neon" +#define QT_FUNCTION_TARGET_STRING_NEON "+neon" // unused: gcc doesn't support function targets on non-aarch64, and on Aarch64 NEON is always available. #ifndef __ARM_NEON__ // __ARM_NEON__ is not defined on AArch64, but we need it in our NEON detection. #define __ARM_NEON__ #endif #endif +// AArch64/ARM64 +#if defined(Q_PROCESSOR_ARM_V8) +#define QT_FUNCTION_TARGET_STRING_CRC32 "+crc" +# include +#endif #undef QT_COMPILER_SUPPORTS_SIMD_ALWAYS @@ -269,6 +285,7 @@ enum CPUFeatures { #if defined(Q_PROCESSOR_ARM) CpuFeatureNEON = 0, CpuFeatureARM_NEON = CpuFeatureNEON, + CpuFeatureCRC32 = 1, #elif defined(Q_PROCESSOR_MIPS) CpuFeatureDSP = 0, CpuFeatureDSPR2 = 1, @@ -396,6 +413,9 @@ static const quint64 qCompilerCpuFeatures = 0 #if defined __ARM_NEON__ | (Q_UINT64_C(1) << CpuFeatureNEON) #endif +#if defined __ARM_FEATURE_CRC32 + | (Q_UINT64_C(1) << CpuFeatureCRC32) +#endif #if defined __mips_dsp | (Q_UINT64_C(1) << CpuFeatureDSP) #endif -- cgit v1.2.3