From 79f1a92995513e0ca82a6f2072ceaa317b77a78a Mon Sep 17 00:00:00 2001 From: dixyes Date: Wed, 1 Dec 2021 13:15:51 +0800 Subject: [PATCH 1/4] Port standard/crc32 for windows arm64 --- ext/standard/crc32.c | 57 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/ext/standard/crc32.c b/ext/standard/crc32.c index d13eee14fbe9d..9476830ca34bd 100644 --- a/ext/standard/crc32.c +++ b/ext/standard/crc32.c @@ -20,7 +20,11 @@ #include "crc32_x86.h" #ifdef HAVE_AARCH64_CRC32 +#ifdef PHP_WIN32 +# include +#else # include +#endif # if defined(__linux__) # include # include @@ -35,6 +39,56 @@ static unsigned long getauxval(unsigned long key) { return 0; return ret; } +# elif defined(PHP_WIN32) +/* +get crc32 support info +this is undocumented, to be confirmed +read id_aa64isar0_el1 from registry HKLM\HARDWARE\DESCRIPTION\System\CentralProcessor\x\CP 4030 +*/ +int winaa64_support_crc32c() { + const WCHAR cpus_key[] = L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\"; + HKEY cpus_handle; + if (ERROR_SUCCESS != RegOpenKeyExW(HKEY_LOCAL_MACHINE, cpus_key, 0, KEY_ENUMERATE_SUB_KEYS, &cpus_handle)) { + return 0; + } + DWORD cpu_index = 0; + WCHAR cpu_num[256] = { 0 }; + uint64_t CP4030 = 0; + WCHAR cpu_key[(sizeof(cpus_key) / sizeof(*cpus_key)) + 256] = L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\"; + while (ERROR_SUCCESS == RegEnumKeyW(cpus_handle, cpu_index++, cpu_num, 255)) { + if (0 != wcscpy_s(&cpu_key[sizeof(cpus_key) / sizeof(*cpus_key) - 1], 256, cpu_num)) { + break; + } + HKEY cpu_handle; + if (ERROR_SUCCESS != RegOpenKeyExW(HKEY_LOCAL_MACHINE, cpu_key, 0, KEY_READ, &cpu_handle)) { + break; + } + DWORD value_type; + uint64_t value; + DWORD value_size = sizeof(value); + if (ERROR_SUCCESS != RegQueryValueExW(cpu_handle, L"CP 4030", NULL, &value_type, (LPBYTE)&value, &value_size)) { + RegCloseKey(cpu_handle); + break; + } + + if (REG_QWORD != value_type) { + RegCloseKey(cpu_handle); + break; + } + //wprintf(L"cp4030 for cpu[%d] \"%s\" is %016zx\n", cpu_index-1, cpu_num, value); + // save any bits not set + CP4030 |= ~value; + + RegCloseKey(cpu_handle); + } + //printf("rev CP4030 is %016zx\n", CP4030); + RegCloseKey(cpus_handle); + if (CP4030 & 0x10000 /* crc32: bit 16-19 (only bit 16 used) */) { + //printf("not supported by at least one cpu\n"); + return 0; + } + return 1; +} # endif static inline int has_crc32_insn() { @@ -53,6 +107,9 @@ static inline int has_crc32_insn() { if (sysctlbyname("hw.optional.armv8_crc32", &res, &reslen, NULL, 0) < 0) res = 0; return res; +# elif defined(WIN32) + res = winaa64_support_crc32c(); + return res; # else res = 0; return res; From 3dc54b58ac081b21ef0b25203ad868c95d741ea4 Mon Sep 17 00:00:00 2001 From: dixyes Date: Wed, 1 Dec 2021 17:57:59 +0800 Subject: [PATCH 2/4] Add arm64 support at php_get_windows_cpu --- ext/standard/info.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ext/standard/info.c b/ext/standard/info.c index acd1a1b36cfce..a7efe770f06e4 100644 --- a/ext/standard/info.c +++ b/ext/standard/info.c @@ -647,6 +647,11 @@ void php_get_windows_cpu(char *buf, int bufsize) case PROCESSOR_ARCHITECTURE_AMD64 : snprintf(buf, bufsize, "AMD64"); break; +#endif +#if defined(PROCESSOR_ARCHITECTURE_ARM64) + case PROCESSOR_ARCHITECTURE_ARM64 : + snprintf(buf, bufsize, "ARM64"); + break; #endif case PROCESSOR_ARCHITECTURE_UNKNOWN : default: From 7693a01053daa81914ab12562cdc70c0a560d13b Mon Sep 17 00:00:00 2001 From: dixyes Date: Mon, 6 Dec 2021 10:46:53 +0800 Subject: [PATCH 3/4] Use IsProcessorFeaturePresent instead --- ext/standard/crc32.c | 52 +------------------------------------------- 1 file changed, 1 insertion(+), 51 deletions(-) diff --git a/ext/standard/crc32.c b/ext/standard/crc32.c index 9476830ca34bd..79ca0cd181d42 100644 --- a/ext/standard/crc32.c +++ b/ext/standard/crc32.c @@ -39,56 +39,6 @@ static unsigned long getauxval(unsigned long key) { return 0; return ret; } -# elif defined(PHP_WIN32) -/* -get crc32 support info -this is undocumented, to be confirmed -read id_aa64isar0_el1 from registry HKLM\HARDWARE\DESCRIPTION\System\CentralProcessor\x\CP 4030 -*/ -int winaa64_support_crc32c() { - const WCHAR cpus_key[] = L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\"; - HKEY cpus_handle; - if (ERROR_SUCCESS != RegOpenKeyExW(HKEY_LOCAL_MACHINE, cpus_key, 0, KEY_ENUMERATE_SUB_KEYS, &cpus_handle)) { - return 0; - } - DWORD cpu_index = 0; - WCHAR cpu_num[256] = { 0 }; - uint64_t CP4030 = 0; - WCHAR cpu_key[(sizeof(cpus_key) / sizeof(*cpus_key)) + 256] = L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\"; - while (ERROR_SUCCESS == RegEnumKeyW(cpus_handle, cpu_index++, cpu_num, 255)) { - if (0 != wcscpy_s(&cpu_key[sizeof(cpus_key) / sizeof(*cpus_key) - 1], 256, cpu_num)) { - break; - } - HKEY cpu_handle; - if (ERROR_SUCCESS != RegOpenKeyExW(HKEY_LOCAL_MACHINE, cpu_key, 0, KEY_READ, &cpu_handle)) { - break; - } - DWORD value_type; - uint64_t value; - DWORD value_size = sizeof(value); - if (ERROR_SUCCESS != RegQueryValueExW(cpu_handle, L"CP 4030", NULL, &value_type, (LPBYTE)&value, &value_size)) { - RegCloseKey(cpu_handle); - break; - } - - if (REG_QWORD != value_type) { - RegCloseKey(cpu_handle); - break; - } - //wprintf(L"cp4030 for cpu[%d] \"%s\" is %016zx\n", cpu_index-1, cpu_num, value); - // save any bits not set - CP4030 |= ~value; - - RegCloseKey(cpu_handle); - } - //printf("rev CP4030 is %016zx\n", CP4030); - RegCloseKey(cpus_handle); - if (CP4030 & 0x10000 /* crc32: bit 16-19 (only bit 16 used) */) { - //printf("not supported by at least one cpu\n"); - return 0; - } - return 1; -} # endif static inline int has_crc32_insn() { @@ -108,7 +58,7 @@ static inline int has_crc32_insn() { res = 0; return res; # elif defined(WIN32) - res = winaa64_support_crc32c(); + res = (int)IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE); return res; # else res = 0; From 872910b8399dba95ed5f93f631abdf8d01e17d04 Mon Sep 17 00:00:00 2001 From: dixyes Date: Mon, 6 Dec 2021 12:08:56 +0800 Subject: [PATCH 4/4] Remove unused include --- ext/standard/crc32.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ext/standard/crc32.c b/ext/standard/crc32.c index 79ca0cd181d42..69d1d55fdd16f 100644 --- a/ext/standard/crc32.c +++ b/ext/standard/crc32.c @@ -20,9 +20,7 @@ #include "crc32_x86.h" #ifdef HAVE_AARCH64_CRC32 -#ifdef PHP_WIN32 -# include -#else +#ifndef PHP_WIN32 # include #endif # if defined(__linux__)