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.
This commit is contained in:
Eric Biggers 2020-10-10 23:02:50 -07:00
parent 7373bdc9ff
commit 2eeaa9282e
5 changed files with 24 additions and 1 deletions

View File

@ -152,6 +152,9 @@ typedef size_t machine_word_t;
#ifndef COMPILER_SUPPORTS_PMULL_TARGET_INTRINSICS #ifndef COMPILER_SUPPORTS_PMULL_TARGET_INTRINSICS
# define COMPILER_SUPPORTS_PMULL_TARGET_INTRINSICS 0 # define COMPILER_SUPPORTS_PMULL_TARGET_INTRINSICS 0
#endif #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 /* _aligned_attribute(n) - declare that the annotated variable, or variables of
* the annotated type, are to be aligned on n-byte boundaries */ * the annotated type, are to be aligned on n-byte boundaries */

View File

@ -119,6 +119,20 @@
# elif __has_builtin(__builtin_neon_vmull_p64) || !defined(__clang__) # elif __has_builtin(__builtin_neon_vmull_p64) || !defined(__clang__)
# define COMPILER_SUPPORTS_PMULL_TARGET_INTRINSICS 1 # define COMPILER_SUPPORTS_PMULL_TARGET_INTRINSICS 1
# endif # 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
# endif /* __arm__ || __aarch64__ */ # endif /* __arm__ || __aarch64__ */

View File

@ -95,6 +95,7 @@ out:
static const struct cpu_feature arm_cpu_feature_table[] = { static const struct cpu_feature arm_cpu_feature_table[] = {
{ARM_CPU_FEATURE_NEON, "neon"}, {ARM_CPU_FEATURE_NEON, "neon"},
{ARM_CPU_FEATURE_PMULL, "pmull"}, {ARM_CPU_FEATURE_PMULL, "pmull"},
{ARM_CPU_FEATURE_CRC32, "crc32"},
}; };
void setup_cpu_features(void) void setup_cpu_features(void)
@ -111,12 +112,16 @@ void setup_cpu_features(void)
features |= ARM_CPU_FEATURE_NEON; features |= ARM_CPU_FEATURE_NEON;
if (hwcap2 & (1 << 1)) /* HWCAP2_PMULL */ if (hwcap2 & (1 << 1)) /* HWCAP2_PMULL */
features |= ARM_CPU_FEATURE_PMULL; features |= ARM_CPU_FEATURE_PMULL;
if (hwcap2 & (1 << 4)) /* HWCAP2_CRC32 */
features |= ARM_CPU_FEATURE_CRC32;
#else #else
STATIC_ASSERT(sizeof(long) == 8); STATIC_ASSERT(sizeof(long) == 8);
if (hwcap & (1 << 1)) /* HWCAP_ASIMD */ if (hwcap & (1 << 1)) /* HWCAP_ASIMD */
features |= ARM_CPU_FEATURE_NEON; features |= ARM_CPU_FEATURE_NEON;
if (hwcap & (1 << 4)) /* HWCAP_PMULL */ if (hwcap & (1 << 4)) /* HWCAP_PMULL */
features |= ARM_CPU_FEATURE_PMULL; features |= ARM_CPU_FEATURE_PMULL;
if (hwcap & (1 << 7)) /* HWCAP_CRC32 */
features |= ARM_CPU_FEATURE_CRC32;
#endif #endif
disable_cpu_features_for_testing(&features, arm_cpu_feature_table, disable_cpu_features_for_testing(&features, arm_cpu_feature_table,

View File

@ -20,6 +20,7 @@
#define ARM_CPU_FEATURE_NEON 0x00000001 #define ARM_CPU_FEATURE_NEON 0x00000001
#define ARM_CPU_FEATURE_PMULL 0x00000002 #define ARM_CPU_FEATURE_PMULL 0x00000002
#define ARM_CPU_FEATURE_CRC32 0x00000004
#define ARM_CPU_FEATURES_KNOWN 0x80000000 #define ARM_CPU_FEATURES_KNOWN 0x80000000

View File

@ -149,7 +149,7 @@ native_build_and_test() {
features=(avx512bw avx2 avx bmi2 pclmul sse2) features=(avx512bw avx2 avx bmi2 pclmul sse2)
;; ;;
arm*|aarch*) arm*|aarch*)
features=(pmull neon) features=(crc32 pmull neon)
;; ;;
esac esac
fi fi