20
20
#include "crc32_x86.h"
21
21
22
22
#ifdef HAVE_AARCH64_CRC32
23
+ #ifdef PHP_WIN32
24
+ # include <intrin.h>
25
+ #else
23
26
# include <arm_acle.h>
27
+ #endif
24
28
# if defined(__linux__ )
25
29
# include <sys/auxv.h>
26
30
# include <asm/hwcap.h>
@@ -35,6 +39,56 @@ static unsigned long getauxval(unsigned long key) {
35
39
return 0 ;
36
40
return ret ;
37
41
}
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
+ }
38
92
# endif
39
93
40
94
static inline int has_crc32_insn () {
@@ -53,6 +107,9 @@ static inline int has_crc32_insn() {
53
107
if (sysctlbyname ("hw.optional.armv8_crc32" , & res , & reslen , NULL , 0 ) < 0 )
54
108
res = 0 ;
55
109
return res ;
110
+ # elif defined(WIN32 )
111
+ res = winaa64_support_crc32c ();
112
+ return res ;
56
113
# else
57
114
res = 0 ;
58
115
return res ;
0 commit comments