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:
committed by
Vladislav Vaintroub
parent
6c6941c9ba
commit
9e1c1d429f
@@ -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
|
||||||
|
Reference in New Issue
Block a user