From 2eeaa9282e4f2eab4bcd97084dbcce31dc0ba824 Mon Sep 17 00:00:00 2001 From: Eric Biggers Date: Sat, 10 Oct 2020 23:02:50 -0700 Subject: [PATCH] lib/arm/cpu_features: recognize the crc32 feature If support for CRC32 instructions is detected, set ARM_CPU_FEATURE_CRC32. Also define COMPILER_SUPPORTS_CRC32_TARGET_INTRINSICS when appropriate, and update run_tests.sh to toggle the crc32 feature for testing. --- common/common_defs.h | 3 +++ common/compiler_gcc.h | 14 ++++++++++++++ lib/arm/cpu_features.c | 5 +++++ lib/arm/cpu_features.h | 1 + tools/run_tests.sh | 2 +- 5 files changed, 24 insertions(+), 1 deletion(-) diff --git a/common/common_defs.h b/common/common_defs.h index dcfcbfa..d56c5cf 100644 --- a/common/common_defs.h +++ b/common/common_defs.h @@ -152,6 +152,9 @@ typedef size_t machine_word_t; #ifndef COMPILER_SUPPORTS_PMULL_TARGET_INTRINSICS # define COMPILER_SUPPORTS_PMULL_TARGET_INTRINSICS 0 #endif +#ifndef COMPILER_SUPPORTS_CRC32_TARGET_INTRINSICS +# define COMPILER_SUPPORTS_CRC32_TARGET_INTRINSICS 0 +#endif /* _aligned_attribute(n) - declare that the annotated variable, or variables of * the annotated type, are to be aligned on n-byte boundaries */ diff --git a/common/compiler_gcc.h b/common/compiler_gcc.h index 4b3b449..0bda3a5 100644 --- a/common/compiler_gcc.h +++ b/common/compiler_gcc.h @@ -119,6 +119,20 @@ # elif __has_builtin(__builtin_neon_vmull_p64) || !defined(__clang__) # define COMPILER_SUPPORTS_PMULL_TARGET_INTRINSICS 1 # endif +# endif + + /* + * Determine whether CRC32 intrinsics are supported. + * + * With gcc r274827 or later (gcc 10.1+, 9.3+, or 8.4+), or with clang, + * they work as expected. (Well, not quite. There's still a bug, but we + * have to work around it later when including arm_acle.h.) + */ +# if GCC_PREREQ(10, 1) || \ + (GCC_PREREQ(9, 3) && !GCC_PREREQ(10, 0)) || \ + (GCC_PREREQ(8, 4) && !GCC_PREREQ(9, 0)) || \ + (defined(__clang__) && __has_builtin(__builtin_arm_crc32b)) +# define COMPILER_SUPPORTS_CRC32_TARGET_INTRINSICS 1 # endif # endif /* __arm__ || __aarch64__ */ diff --git a/lib/arm/cpu_features.c b/lib/arm/cpu_features.c index c4556a3..60b1be3 100644 --- a/lib/arm/cpu_features.c +++ b/lib/arm/cpu_features.c @@ -95,6 +95,7 @@ out: static const struct cpu_feature arm_cpu_feature_table[] = { {ARM_CPU_FEATURE_NEON, "neon"}, {ARM_CPU_FEATURE_PMULL, "pmull"}, + {ARM_CPU_FEATURE_CRC32, "crc32"}, }; void setup_cpu_features(void) @@ -111,12 +112,16 @@ void setup_cpu_features(void) features |= ARM_CPU_FEATURE_NEON; if (hwcap2 & (1 << 1)) /* HWCAP2_PMULL */ features |= ARM_CPU_FEATURE_PMULL; + if (hwcap2 & (1 << 4)) /* HWCAP2_CRC32 */ + features |= ARM_CPU_FEATURE_CRC32; #else STATIC_ASSERT(sizeof(long) == 8); if (hwcap & (1 << 1)) /* HWCAP_ASIMD */ features |= ARM_CPU_FEATURE_NEON; if (hwcap & (1 << 4)) /* HWCAP_PMULL */ features |= ARM_CPU_FEATURE_PMULL; + if (hwcap & (1 << 7)) /* HWCAP_CRC32 */ + features |= ARM_CPU_FEATURE_CRC32; #endif disable_cpu_features_for_testing(&features, arm_cpu_feature_table, diff --git a/lib/arm/cpu_features.h b/lib/arm/cpu_features.h index a491436..69d7235 100644 --- a/lib/arm/cpu_features.h +++ b/lib/arm/cpu_features.h @@ -20,6 +20,7 @@ #define ARM_CPU_FEATURE_NEON 0x00000001 #define ARM_CPU_FEATURE_PMULL 0x00000002 +#define ARM_CPU_FEATURE_CRC32 0x00000004 #define ARM_CPU_FEATURES_KNOWN 0x80000000 diff --git a/tools/run_tests.sh b/tools/run_tests.sh index b1b3c7e..59e11c8 100755 --- a/tools/run_tests.sh +++ b/tools/run_tests.sh @@ -149,7 +149,7 @@ native_build_and_test() { features=(avx512bw avx2 avx bmi2 pclmul sse2) ;; arm*|aarch*) - features=(pmull neon) + features=(crc32 pmull neon) ;; esac fi