aboutsummaryrefslogtreecommitdiff
path: root/platform/linux-generic/arch/aarch64
diff options
context:
space:
mode:
authorMalvika Gupta <Malvika.Gupta@arm.com>2021-01-20 16:13:23 -0600
committerPetri Savolainen <petri.savolainen@nokia.com>2021-01-26 09:48:50 +0200
commitdf3abb351d23fbd4a738e43ab0f6b25de7230679 (patch)
treec63e596ee322739133d74795fee33026392eebbd /platform/linux-generic/arch/aarch64
parentd07a44c6ed222746d661f3c6b91d3c7f3b5f799b (diff)
linux-gen: hash: add armv8-a crc32 hash functions
Add Armv8-A architecture-specific CRC32 and CRC32C extensions. Signed-off-by: Malvika Gupta <Malvika.Gupta@arm.com> Signed-off-by: Matias Elo <matias.elo@nokia.com> Reviewed-by: Govindarajan Mohandoss <govindarajan.mohandoss@arm.com> Reviewed-by: Jere Leppänen <jere.leppanen@nokia.com> Reviewed-by: Petri Savolainen <petri.savolainen@nokia.com>
Diffstat (limited to 'platform/linux-generic/arch/aarch64')
-rw-r--r--platform/linux-generic/arch/aarch64/odp/api/abi/hash_crc32.h103
1 files changed, 103 insertions, 0 deletions
diff --git a/platform/linux-generic/arch/aarch64/odp/api/abi/hash_crc32.h b/platform/linux-generic/arch/aarch64/odp/api/abi/hash_crc32.h
new file mode 100644
index 000000000..fd7bf91c6
--- /dev/null
+++ b/platform/linux-generic/arch/aarch64/odp/api/abi/hash_crc32.h
@@ -0,0 +1,103 @@
+/* Copyright (c) 2021 ARM Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ODP_API_ABI_HASH_CRC32_H_
+#define ODP_API_ABI_HASH_CRC32_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+uint32_t _odp_hash_crc32_generic(const void *data, uint32_t data_len,
+ uint32_t init_val);
+uint32_t _odp_hash_crc32c_generic(const void *data, uint32_t data_len,
+ uint32_t init_val);
+
+#ifdef __ARM_FEATURE_CRC32
+
+#include <arm_acle.h>
+
+static inline uint32_t _odp_hash_crc32(const void *data_ptr, uint32_t data_len,
+ uint32_t init_val)
+{
+ uint32_t i;
+ uintptr_t pd = (uintptr_t)data_ptr;
+
+ for (i = 0; i < data_len / 8; i++) {
+ init_val = __crc32d(init_val, *(const uint64_t *)pd);
+ pd += 8;
+ }
+
+ if (data_len & 0x4) {
+ init_val = __crc32w(init_val, *(const uint32_t *)pd);
+ pd += 4;
+ }
+
+ if (data_len & 0x2) {
+ init_val = __crc32h(init_val, *(const uint16_t *)pd);
+ pd += 2;
+ }
+
+ if (data_len & 0x1)
+ init_val = __crc32b(init_val, *(const uint8_t *)pd);
+
+ return init_val;
+}
+
+static inline uint32_t _odp_hash_crc32c(const void *data, uint32_t data_len,
+ uint32_t init_val)
+{
+ uint32_t i;
+ uintptr_t pd = (uintptr_t)data;
+
+ for (i = 0; i < data_len / 8; i++) {
+ init_val = __crc32cd(init_val, *(const uint64_t *)pd);
+ pd += 8;
+ }
+
+ if (data_len & 0x4) {
+ init_val = __crc32cw(init_val, *(const uint32_t *)pd);
+ pd += 4;
+ }
+
+ if (data_len & 0x2) {
+ init_val = __crc32ch(init_val, *(const uint16_t *)pd);
+ pd += 2;
+ }
+
+ if (data_len & 0x1)
+ init_val = __crc32cb(init_val, *(const uint8_t *)pd);
+
+ return init_val;
+}
+
+#else /* __ARM_FEATURE_CRC32 */
+
+/*
+ * Fall back to software implementation
+ */
+
+static inline uint32_t _odp_hash_crc32(const void *data, uint32_t data_len,
+ uint32_t init_val)
+{
+ return _odp_hash_crc32_generic(data, data_len, init_val);
+}
+
+static inline uint32_t _odp_hash_crc32c(const void *data, uint32_t data_len,
+ uint32_t init_val)
+{
+ return _odp_hash_crc32c_generic(data, data_len, init_val);
+}
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif