diff options
Diffstat (limited to 'sys/libkern/crc32.c')
-rw-r--r-- | sys/libkern/crc32.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/sys/libkern/crc32.c b/sys/libkern/crc32.c index 281c4b6..b0a8ce0 100644 --- a/sys/libkern/crc32.c +++ b/sys/libkern/crc32.c @@ -54,6 +54,10 @@ __FBSDID("$FreeBSD$"); #include <machine/specialreg.h> #endif +#if defined(__aarch64__) +#include <machine/cpu.h> +#endif + const uint32_t crc32_tab[] = { 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, @@ -760,6 +764,18 @@ calculate_crc32c(uint32_t crc32c, return (sse42_crc32c(crc32c, buffer, length)); } else #endif +#if defined(__aarch64__) + uint64_t reg; + + /* + * We only test for CRC32 support on the CPU with index 0 assuming that + * this applies to all CPUs. + */ + reg = READ_SPECIALREG(id_aa64isar0_el1); + if (ID_AA64ISAR0_CRC32(reg) != ID_AA64ISAR0_CRC32_NONE) { + return (armv8_crc32c(crc32c, buffer, length)); + } else +#endif if (length < 4) { return (singletable_crc32c(crc32c, buffer, length)); } else { |