diff --git a/include/spdk/crc32.h b/include/spdk/crc32.h index 85e0112df..2074d3ad8 100644 --- a/include/spdk/crc32.h +++ b/include/spdk/crc32.h @@ -45,6 +45,17 @@ extern "C" { #endif +#if defined(__aarch64__) || defined(__AARCH64__) +#ifdef __ARM_FEATURE_CRC32 +#define SPDK_HAVE_ARM_CRC +#include +#endif +#endif + +#if defined(__x86_64__) && defined(__SSE4_2__) +#define SPDK_HAVE_SSE4_2 +#include +#endif /** * IEEE CRC-32 polynomial (bit reflected) */ diff --git a/lib/util/crc32c.c b/lib/util/crc32c.c index e95283b3a..a8a35a57a 100644 --- a/lib/util/crc32c.c +++ b/lib/util/crc32c.c @@ -33,8 +33,7 @@ #include "spdk/crc32.h" -#if defined(__x86_64__) && defined(__SSE4_2__) -#include +#ifdef SPDK_HAVE_SSE4_2 uint32_t spdk_crc32c_update(const void *buf, size_t len, uint32_t crc) @@ -70,7 +69,32 @@ spdk_crc32c_update(const void *buf, size_t len, uint32_t crc) return crc; } -#else /* SSE 4.2 (CRC32 instruction) not available */ +#elif defined(SPDK_HAVE_ARM_CRC) + +uint32_t +spdk_crc32c_update(const void *buf, size_t len, uint32_t crc) +{ + size_t count; + + count = len / 8; + while (count--) { + uint64_t block; + + memcpy(&block, buf, sizeof(block)); + crc = __crc32cd(crc, block); + buf += sizeof(block); + } + + count = len & 7; + while (count--) { + crc = __crc32cb(crc, *(const uint8_t *)buf); + buf++; + } + + return crc; +} + +#else /* Neither SSE 4.2 nor ARM CRC32 instructions available */ static struct spdk_crc32_table g_crc32c_table; diff --git a/mk/spdk.common.mk b/mk/spdk.common.mk index 2812e204a..721513a2e 100644 --- a/mk/spdk.common.mk +++ b/mk/spdk.common.mk @@ -81,6 +81,9 @@ endif ifeq ($(TARGET_MACHINE),x86_64) COMMON_CFLAGS += -march=native endif +ifeq ($(TARGET_MACHINE),aarch64) +COMMON_CFLAGS += -march=armv8-a+crc +endif ifeq ($(CONFIG_WERROR), y) COMMON_CFLAGS += -Werror