#include "spdk/crc32.h"
+#if defined(__aarch64__) || defined(__AARCH64__)
+#ifdef __ARM_FEATURE_CRC32
+#define SPDK_HAVE_ARM_CRC
+#include <arm_acle.h>
+#endif
+#endif
+
#if defined(__x86_64__) && defined(__SSE4_2__)
+#ifdef SPDK_CONFIG_ISAL
+#define SPDK_HAVE_ISAL
+#include <isa-l/include/crc.h>
+#else
+#define SPDK_HAVE_SSE4_2
#include <x86intrin.h>
+#endif
+#endif
+
+#ifdef SPDK_HAVE_ISAL
+
+uint32_t
+spdk_crc32c_update(const void *buf, size_t len, uint32_t crc)
+{
+ return crc32_iscsi((unsigned char *)buf, len, crc);
+}
+
+#elif defined(SPDK_HAVE_SSE4_2)
uint32_t
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;