ARMv8: add crc32 feature detection.
Change-Id: I3cfac90dfa137d0bf3d124d87262eb2dbb56459c Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
parent
9a969182cf
commit
4417458d62
@ -243,6 +243,9 @@ const char msg2[] = "==Qt=magic=Qt== Sub-architecture:"
|
|||||||
#ifdef __IWMMXT__
|
#ifdef __IWMMXT__
|
||||||
" iwmmxt"
|
" iwmmxt"
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef __ARM_FEATURE_CRC32
|
||||||
|
" crc32"
|
||||||
|
#endif
|
||||||
|
|
||||||
// -- SPARC --
|
// -- SPARC --
|
||||||
#ifdef __VIS__
|
#ifdef __VIS__
|
||||||
|
@ -65,8 +65,15 @@
|
|||||||
#define HWCAP_VFPv3 8192
|
#define HWCAP_VFPv3 8192
|
||||||
#define HWCAP_VFPv3D16 16384
|
#define HWCAP_VFPv3D16 16384
|
||||||
|
|
||||||
|
// copied from <asm/hwcap.h> (ARM):
|
||||||
|
#define HWCAP2_CRC32 (1 << 4)
|
||||||
|
|
||||||
|
// copied from <asm/hwcap.h> (Aarch64)
|
||||||
|
#define HWCAP_CRC32 (1 << 7)
|
||||||
|
|
||||||
// copied from <linux/auxvec.h>
|
// copied from <linux/auxvec.h>
|
||||||
#define AT_HWCAP 16 /* arch dependent hints at CPU capabilities */
|
#define AT_HWCAP 16 /* arch dependent hints at CPU capabilities */
|
||||||
|
#define AT_HWCAP2 26 /* extension of AT_HWCAP */
|
||||||
|
|
||||||
#elif defined(Q_CC_GHS)
|
#elif defined(Q_CC_GHS)
|
||||||
#include <INTEGRITY_types.h>
|
#include <INTEGRITY_types.h>
|
||||||
@ -103,7 +110,16 @@ static inline quint64 detectProcessorFeatures()
|
|||||||
{
|
{
|
||||||
quint64 features = 0;
|
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);
|
int auxv = qt_safe_open("/proc/self/auxv", O_RDONLY);
|
||||||
if (auxv != -1) {
|
if (auxv != -1) {
|
||||||
unsigned long vector[64];
|
unsigned long vector[64];
|
||||||
@ -116,12 +132,25 @@ static inline quint64 detectProcessorFeatures()
|
|||||||
}
|
}
|
||||||
|
|
||||||
int max = nread / (sizeof vector[0]);
|
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 (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)
|
if (vector[i+1] & HWCAP_NEON)
|
||||||
features |= Q_UINT64_C(1) << CpuFeatureNEON;
|
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);
|
qt_safe_close(auxv);
|
||||||
@ -133,6 +162,9 @@ static inline quint64 detectProcessorFeatures()
|
|||||||
#if defined(__ARM_NEON__)
|
#if defined(__ARM_NEON__)
|
||||||
features = Q_UINT64_C(1) << CpuFeatureNEON;
|
features = Q_UINT64_C(1) << CpuFeatureNEON;
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(__ARM_FEATURE_CRC32)
|
||||||
|
features = Q_UINT64_C(1) << CpuFeatureCRC32;
|
||||||
|
#endif
|
||||||
|
|
||||||
return features;
|
return features;
|
||||||
}
|
}
|
||||||
@ -498,9 +530,13 @@ static inline uint detectProcessorFeatures()
|
|||||||
#if defined(Q_PROCESSOR_ARM)
|
#if defined(Q_PROCESSOR_ARM)
|
||||||
/* Data:
|
/* Data:
|
||||||
neon
|
neon
|
||||||
|
crc32
|
||||||
*/
|
*/
|
||||||
static const char features_string[] = " neon\0";
|
static const char features_string[] =
|
||||||
static const int features_indices[] = { 0 };
|
" neon\0"
|
||||||
|
" crc32\0"
|
||||||
|
"\0";
|
||||||
|
static const int features_indices[] = { 0, 6 };
|
||||||
#elif defined(Q_PROCESSOR_MIPS)
|
#elif defined(Q_PROCESSOR_MIPS)
|
||||||
/* Data:
|
/* Data:
|
||||||
dsp
|
dsp
|
||||||
|
@ -138,7 +138,18 @@
|
|||||||
|
|
||||||
#define QT_COMPILER_SUPPORTS(x) (QT_COMPILER_SUPPORTS_ ## x - 0)
|
#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(Q_CC_GNU) && !defined(Q_CC_CLANG) && (__GNUC__-0) * 100 + (__GNUC_MINOR__-0) >= 409)) \
|
||||||
&& !defined(QT_BOOTSTRAPPED)
|
&& !defined(QT_BOOTSTRAPPED)
|
||||||
# define QT_COMPILER_SUPPORTS_SIMD_ALWAYS
|
# define QT_COMPILER_SUPPORTS_SIMD_ALWAYS
|
||||||
@ -253,12 +264,17 @@
|
|||||||
// note: as of GCC 4.9, does not support function targets for ARM
|
// note: as of GCC 4.9, does not support function targets for ARM
|
||||||
#if defined(__ARM_NEON) || defined(__ARM_NEON__)
|
#if defined(__ARM_NEON) || defined(__ARM_NEON__)
|
||||||
#include <arm_neon.h>
|
#include <arm_neon.h>
|
||||||
#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__
|
#ifndef __ARM_NEON__
|
||||||
// __ARM_NEON__ is not defined on AArch64, but we need it in our NEON detection.
|
// __ARM_NEON__ is not defined on AArch64, but we need it in our NEON detection.
|
||||||
#define __ARM_NEON__
|
#define __ARM_NEON__
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
// AArch64/ARM64
|
||||||
|
#if defined(Q_PROCESSOR_ARM_V8)
|
||||||
|
#define QT_FUNCTION_TARGET_STRING_CRC32 "+crc"
|
||||||
|
# include <arm_acle.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#undef QT_COMPILER_SUPPORTS_SIMD_ALWAYS
|
#undef QT_COMPILER_SUPPORTS_SIMD_ALWAYS
|
||||||
|
|
||||||
@ -269,6 +285,7 @@ enum CPUFeatures {
|
|||||||
#if defined(Q_PROCESSOR_ARM)
|
#if defined(Q_PROCESSOR_ARM)
|
||||||
CpuFeatureNEON = 0,
|
CpuFeatureNEON = 0,
|
||||||
CpuFeatureARM_NEON = CpuFeatureNEON,
|
CpuFeatureARM_NEON = CpuFeatureNEON,
|
||||||
|
CpuFeatureCRC32 = 1,
|
||||||
#elif defined(Q_PROCESSOR_MIPS)
|
#elif defined(Q_PROCESSOR_MIPS)
|
||||||
CpuFeatureDSP = 0,
|
CpuFeatureDSP = 0,
|
||||||
CpuFeatureDSPR2 = 1,
|
CpuFeatureDSPR2 = 1,
|
||||||
@ -396,6 +413,9 @@ static const quint64 qCompilerCpuFeatures = 0
|
|||||||
#if defined __ARM_NEON__
|
#if defined __ARM_NEON__
|
||||||
| (Q_UINT64_C(1) << CpuFeatureNEON)
|
| (Q_UINT64_C(1) << CpuFeatureNEON)
|
||||||
#endif
|
#endif
|
||||||
|
#if defined __ARM_FEATURE_CRC32
|
||||||
|
| (Q_UINT64_C(1) << CpuFeatureCRC32)
|
||||||
|
#endif
|
||||||
#if defined __mips_dsp
|
#if defined __mips_dsp
|
||||||
| (Q_UINT64_C(1) << CpuFeatureDSP)
|
| (Q_UINT64_C(1) << CpuFeatureDSP)
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user