Skip to content

Commit 9e1c1d4

Browse files
coneco-cyvaintroub
authored andcommitted
crc32 compatibility on Windows on ARM64
1 parent 6c6941c commit 9e1c1d4

File tree

1 file changed

+39
-31
lines changed

1 file changed

+39
-31
lines changed

mysys/crc32/crc32_arm64.c

Lines changed: 39 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4,31 +4,38 @@
44
#include <stddef.h>
55

66
typedef unsigned (*my_crc32_t)(unsigned, const void *, size_t);
7+
unsigned crc32_aarch64(unsigned, const void *, size_t);
78

89
#ifdef HAVE_ARMV8_CRC
910

10-
#ifdef _WIN32
11-
#include <windows.h>
11+
# ifdef HAVE_ARMV8_CRYPTO
12+
static unsigned crc32c_aarch64_pmull(unsigned, const void *, size_t);
13+
# endif
14+
15+
# ifdef _WIN32
16+
# include <windows.h>
17+
# ifdef __clang__
18+
# include <arm_acle.h>
19+
# include <arm_neon.h>
20+
# endif
1221
int crc32_aarch64_available(void)
1322
{
1423
return IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE);
1524
}
1625

17-
const char *crc32c_aarch64_available(void)
26+
unsigned crc32c_aarch64(unsigned, const void *, size_t);
27+
28+
my_crc32_t crc32c_aarch64_available(void)
1829
{
1930
if (crc32_aarch64_available() == 0)
2031
return NULL;
2132
/* TODO : pmull seems supported, but does not compile*/
22-
return "Using ARMv8 crc32 instructions";
33+
return crc32c_aarch64;
2334
}
24-
#endif /* _WIN32 */
2535

26-
#ifdef HAVE_ARMV8_CRYPTO
27-
static unsigned crc32c_aarch64_pmull(unsigned, const void *, size_t);
28-
# endif
29-
30-
# ifdef __APPLE__
31-
# include <sys/sysctl.h>
36+
# else /* _WIN32 */
37+
# ifdef __APPLE__
38+
# include <sys/sysctl.h>
3239

3340
int crc32_aarch64_available(void)
3441
{
@@ -41,34 +48,34 @@ int crc32_aarch64_available(void)
4148

4249
my_crc32_t crc32c_aarch64_available(void)
4350
{
44-
# ifdef HAVE_ARMV8_CRYPTO
51+
# ifdef HAVE_ARMV8_CRYPTO
4552
if (crc32_aarch64_available())
4653
return crc32c_aarch64_pmull;
47-
# endif
54+
# endif
4855
return NULL;
4956
}
5057

51-
# else /* __APPLE__ */
52-
# include <sys/auxv.h>
53-
# ifdef __FreeBSD__
58+
# else /* __APPLE__ */
59+
# include <sys/auxv.h>
60+
# ifdef __FreeBSD__
5461
static unsigned long getauxval(unsigned int key)
5562
{
5663
unsigned long val;
5764
if (elf_aux_info(key, (void *)&val, (int)sizeof(val) != 0))
5865
return 0ul;
5966
return val;
6067
}
61-
# else
62-
# include <asm/hwcap.h>
63-
# endif
68+
# else
69+
# include <asm/hwcap.h>
70+
# endif
6471

65-
# ifndef HWCAP_CRC32
66-
# define HWCAP_CRC32 (1 << 7)
67-
# endif
72+
# ifndef HWCAP_CRC32
73+
# define HWCAP_CRC32 (1 << 7)
74+
# endif
6875

69-
# ifndef HWCAP_PMULL
70-
# define HWCAP_PMULL (1 << 4)
71-
# endif
76+
# ifndef HWCAP_PMULL
77+
# define HWCAP_PMULL (1 << 4)
78+
# endif
7279

7380
/* ARM made crc32 default from ARMv8.1 but optional in ARMv8A
7481
* Runtime check API.
@@ -78,24 +85,25 @@ int crc32_aarch64_available(void)
7885
unsigned long auxv= getauxval(AT_HWCAP);
7986
return (auxv & HWCAP_CRC32) != 0;
8087
}
81-
# endif /* __APPLE__ */
88+
# endif /* __APPLE__ */
8289

83-
# ifndef __APPLE__
90+
# ifndef __APPLE__
8491
static unsigned crc32c_aarch64(unsigned, const void *, size_t);
8592

8693
my_crc32_t crc32c_aarch64_available(void)
8794
{
8895
unsigned long auxv= getauxval(AT_HWCAP);
8996
if (!(auxv & HWCAP_CRC32))
9097
return NULL;
91-
# ifdef HAVE_ARMV8_CRYPTO
98+
# ifdef HAVE_ARMV8_CRYPTO
9299
/* Raspberry Pi 4 supports crc32 but doesn't support pmull (MDEV-23030). */
93100
if (auxv & HWCAP_PMULL)
94101
return crc32c_aarch64_pmull;
95-
# endif
102+
# endif
96103
return crc32c_aarch64;
97104
}
98-
# endif /* __APPLE__ */
105+
# endif /* __APPLE__ */
106+
# endif /* _WIN32 */
99107

100108
const char *crc32c_aarch64_impl(my_crc32_t c)
101109
{
@@ -370,7 +378,7 @@ static unsigned crc32c_aarch64_pmull(unsigned crc, const void *buf, size_t len)
370378
/* There are multiple approaches to calculate crc.
371379
Approach-1: Process 8 bytes then 4 bytes then 2 bytes and then 1 bytes
372380
Approach-2: Process 8 bytes and remaining workload using 1 bytes
373-
Apporach-3: Process 64 bytes at once by issuing 8 crc call and remaining
381+
Approach-3: Process 64 bytes at once by issuing 8 crc call and remaining
374382
using 8/1 combination.
375383
376384
Based on micro-benchmark testing we found that Approach-2 works best especially

0 commit comments

Comments
 (0)