diff options
author | Malvika Gupta <Malvika.Gupta@arm.com> | 2021-01-20 16:13:23 -0600 |
---|---|---|
committer | Petri Savolainen <petri.savolainen@nokia.com> | 2021-01-26 09:48:50 +0200 |
commit | df3abb351d23fbd4a738e43ab0f6b25de7230679 (patch) | |
tree | c63e596ee322739133d74795fee33026392eebbd | |
parent | d07a44c6ed222746d661f3c6b91d3c7f3b5f799b (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>
-rw-r--r-- | platform/linux-generic/Makefile.am | 2 | ||||
-rw-r--r-- | platform/linux-generic/arch/aarch64/odp/api/abi/hash_crc32.h | 103 |
2 files changed, 104 insertions, 1 deletions
diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am index 645022dd6..70ab7ab7c 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -287,7 +287,7 @@ __LIB__libodp_linux_la_SOURCES += arch/default/odp_cpu_cycles.c \ arch/aarch64/odp_sysinfo_parse.c odpapiabiarchinclude_HEADERS += arch/default/odp/api/abi/cpu_inlines.h \ arch/default/odp/api/abi/cpu_time.h \ - arch/default/odp/api/abi/hash_crc32.h + arch/aarch64/odp/api/abi/hash_crc32.h if !ODP_ABI_COMPAT odpapiabiarchinclude_HEADERS += arch/aarch64/odp/api/abi/cpu.h endif 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 |