Skip to content

Commit 79f1a92

Browse files
dixyescmb69
authored andcommitted
Port standard/crc32 for windows arm64
1 parent 8fec415 commit 79f1a92

File tree

1 file changed

+57
-0
lines changed

1 file changed

+57
-0
lines changed

ext/standard/crc32.c

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,11 @@
2020
#include "crc32_x86.h"
2121

2222
#ifdef HAVE_AARCH64_CRC32
23+
#ifdef PHP_WIN32
24+
# include <intrin.h>
25+
#else
2326
# include <arm_acle.h>
27+
#endif
2428
# if defined(__linux__)
2529
# include <sys/auxv.h>
2630
# include <asm/hwcap.h>
@@ -35,6 +39,56 @@ static unsigned long getauxval(unsigned long key) {
3539
return 0;
3640
return ret;
3741
}
42+
# elif defined(PHP_WIN32)
43+
/*
44+
get crc32 support info
45+
this is undocumented, to be confirmed
46+
read id_aa64isar0_el1 from registry HKLM\HARDWARE\DESCRIPTION\System\CentralProcessor\x\CP 4030
47+
*/
48+
int winaa64_support_crc32c() {
49+
const WCHAR cpus_key[] = L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\";
50+
HKEY cpus_handle;
51+
if (ERROR_SUCCESS != RegOpenKeyExW(HKEY_LOCAL_MACHINE, cpus_key, 0, KEY_ENUMERATE_SUB_KEYS, &cpus_handle)) {
52+
return 0;
53+
}
54+
DWORD cpu_index = 0;
55+
WCHAR cpu_num[256] = { 0 };
56+
uint64_t CP4030 = 0;
57+
WCHAR cpu_key[(sizeof(cpus_key) / sizeof(*cpus_key)) + 256] = L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\";
58+
while (ERROR_SUCCESS == RegEnumKeyW(cpus_handle, cpu_index++, cpu_num, 255)) {
59+
if (0 != wcscpy_s(&cpu_key[sizeof(cpus_key) / sizeof(*cpus_key) - 1], 256, cpu_num)) {
60+
break;
61+
}
62+
HKEY cpu_handle;
63+
if (ERROR_SUCCESS != RegOpenKeyExW(HKEY_LOCAL_MACHINE, cpu_key, 0, KEY_READ, &cpu_handle)) {
64+
break;
65+
}
66+
DWORD value_type;
67+
uint64_t value;
68+
DWORD value_size = sizeof(value);
69+
if (ERROR_SUCCESS != RegQueryValueExW(cpu_handle, L"CP 4030", NULL, &value_type, (LPBYTE)&value, &value_size)) {
70+
RegCloseKey(cpu_handle);
71+
break;
72+
}
73+
74+
if (REG_QWORD != value_type) {
75+
RegCloseKey(cpu_handle);
76+
break;
77+
}
78+
//wprintf(L"cp4030 for cpu[%d] \"%s\" is %016zx\n", cpu_index-1, cpu_num, value);
79+
// save any bits not set
80+
CP4030 |= ~value;
81+
82+
RegCloseKey(cpu_handle);
83+
}
84+
//printf("rev CP4030 is %016zx\n", CP4030);
85+
RegCloseKey(cpus_handle);
86+
if (CP4030 & 0x10000 /* crc32: bit 16-19 (only bit 16 used) */) {
87+
//printf("not supported by at least one cpu\n");
88+
return 0;
89+
}
90+
return 1;
91+
}
3892
# endif
3993

4094
static inline int has_crc32_insn() {
@@ -53,6 +107,9 @@ static inline int has_crc32_insn() {
53107
if (sysctlbyname("hw.optional.armv8_crc32", &res, &reslen, NULL, 0) < 0)
54108
res = 0;
55109
return res;
110+
# elif defined(WIN32)
111+
res = winaa64_support_crc32c();
112+
return res;
56113
# else
57114
res = 0;
58115
return res;

0 commit comments

Comments
 (0)