1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-09 22:24:09 +03:00

crc32 compatibility on Windows on ARM64

This commit is contained in:
chengya
2025-05-23 10:34:21 +08:00
committed by Vladislav Vaintroub
parent 6c6941c9ba
commit 9e1c1d429f

View File

@@ -4,31 +4,38 @@
#include <stddef.h> #include <stddef.h>
typedef unsigned (*my_crc32_t)(unsigned, const void *, size_t); typedef unsigned (*my_crc32_t)(unsigned, const void *, size_t);
unsigned crc32_aarch64(unsigned, const void *, size_t);
#ifdef HAVE_ARMV8_CRC #ifdef HAVE_ARMV8_CRC
#ifdef _WIN32 # ifdef HAVE_ARMV8_CRYPTO
#include <windows.h> static unsigned crc32c_aarch64_pmull(unsigned, const void *, size_t);
# endif
# ifdef _WIN32
# include <windows.h>
# ifdef __clang__
# include <arm_acle.h>
# include <arm_neon.h>
# endif
int crc32_aarch64_available(void) int crc32_aarch64_available(void)
{ {
return IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE); return IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE);
} }
const char *crc32c_aarch64_available(void) unsigned crc32c_aarch64(unsigned, const void *, size_t);
my_crc32_t crc32c_aarch64_available(void)
{ {
if (crc32_aarch64_available() == 0) if (crc32_aarch64_available() == 0)
return NULL; return NULL;
/* TODO : pmull seems supported, but does not compile*/ /* TODO : pmull seems supported, but does not compile*/
return "Using ARMv8 crc32 instructions"; return crc32c_aarch64;
} }
#endif /* _WIN32 */
#ifdef HAVE_ARMV8_CRYPTO # else /* _WIN32 */
static unsigned crc32c_aarch64_pmull(unsigned, const void *, size_t); # ifdef __APPLE__
# endif # include <sys/sysctl.h>
# ifdef __APPLE__
# include <sys/sysctl.h>
int crc32_aarch64_available(void) int crc32_aarch64_available(void)
{ {
@@ -41,16 +48,16 @@ int crc32_aarch64_available(void)
my_crc32_t crc32c_aarch64_available(void) my_crc32_t crc32c_aarch64_available(void)
{ {
# ifdef HAVE_ARMV8_CRYPTO # ifdef HAVE_ARMV8_CRYPTO
if (crc32_aarch64_available()) if (crc32_aarch64_available())
return crc32c_aarch64_pmull; return crc32c_aarch64_pmull;
# endif # endif
return NULL; return NULL;
} }
# else /* __APPLE__ */ # else /* __APPLE__ */
# include <sys/auxv.h> # include <sys/auxv.h>
# ifdef __FreeBSD__ # ifdef __FreeBSD__
static unsigned long getauxval(unsigned int key) static unsigned long getauxval(unsigned int key)
{ {
unsigned long val; unsigned long val;
@@ -58,17 +65,17 @@ static unsigned long getauxval(unsigned int key)
return 0ul; return 0ul;
return val; return val;
} }
# else # else
# include <asm/hwcap.h> # include <asm/hwcap.h>
# endif # endif
# ifndef HWCAP_CRC32 # ifndef HWCAP_CRC32
# define HWCAP_CRC32 (1 << 7) # define HWCAP_CRC32 (1 << 7)
# endif # endif
# ifndef HWCAP_PMULL # ifndef HWCAP_PMULL
# define HWCAP_PMULL (1 << 4) # define HWCAP_PMULL (1 << 4)
# endif # endif
/* ARM made crc32 default from ARMv8.1 but optional in ARMv8A /* ARM made crc32 default from ARMv8.1 but optional in ARMv8A
* Runtime check API. * Runtime check API.
@@ -78,9 +85,9 @@ int crc32_aarch64_available(void)
unsigned long auxv= getauxval(AT_HWCAP); unsigned long auxv= getauxval(AT_HWCAP);
return (auxv & HWCAP_CRC32) != 0; return (auxv & HWCAP_CRC32) != 0;
} }
# endif /* __APPLE__ */ # endif /* __APPLE__ */
# ifndef __APPLE__ # ifndef __APPLE__
static unsigned crc32c_aarch64(unsigned, const void *, size_t); static unsigned crc32c_aarch64(unsigned, const void *, size_t);
my_crc32_t crc32c_aarch64_available(void) my_crc32_t crc32c_aarch64_available(void)
@@ -88,14 +95,15 @@ my_crc32_t crc32c_aarch64_available(void)
unsigned long auxv= getauxval(AT_HWCAP); unsigned long auxv= getauxval(AT_HWCAP);
if (!(auxv & HWCAP_CRC32)) if (!(auxv & HWCAP_CRC32))
return NULL; return NULL;
# ifdef HAVE_ARMV8_CRYPTO # ifdef HAVE_ARMV8_CRYPTO
/* Raspberry Pi 4 supports crc32 but doesn't support pmull (MDEV-23030). */ /* Raspberry Pi 4 supports crc32 but doesn't support pmull (MDEV-23030). */
if (auxv & HWCAP_PMULL) if (auxv & HWCAP_PMULL)
return crc32c_aarch64_pmull; return crc32c_aarch64_pmull;
# endif # endif
return crc32c_aarch64; return crc32c_aarch64;
} }
# endif /* __APPLE__ */ # endif /* __APPLE__ */
# endif /* _WIN32 */
const char *crc32c_aarch64_impl(my_crc32_t c) const char *crc32c_aarch64_impl(my_crc32_t c)
{ {
@@ -370,7 +378,7 @@ static unsigned crc32c_aarch64_pmull(unsigned crc, const void *buf, size_t len)
/* There are multiple approaches to calculate crc. /* There are multiple approaches to calculate crc.
Approach-1: Process 8 bytes then 4 bytes then 2 bytes and then 1 bytes Approach-1: Process 8 bytes then 4 bytes then 2 bytes and then 1 bytes
Approach-2: Process 8 bytes and remaining workload using 1 bytes Approach-2: Process 8 bytes and remaining workload using 1 bytes
Apporach-3: Process 64 bytes at once by issuing 8 crc call and remaining Approach-3: Process 64 bytes at once by issuing 8 crc call and remaining
using 8/1 combination. using 8/1 combination.
Based on micro-benchmark testing we found that Approach-2 works best especially Based on micro-benchmark testing we found that Approach-2 works best especially