21
21
#include "crc32.h"
22
22
23
23
#if defined(__aarch64__ )
24
- # pragma GCC target ("+nothing+crc")
25
24
# include <arm_acle.h>
26
25
# if defined(__linux__ )
27
26
# include <sys/auxv.h>
@@ -44,6 +43,31 @@ static inline int has_crc32_insn() {
44
43
return res ;
45
44
# endif
46
45
}
46
+
47
+ # pragma GCC push_options
48
+ # pragma GCC target ("+nothing+crc")
49
+ static uint32_t crc32_aarch64 (uint32_t crc , char * p , size_t nr ) {
50
+ while (nr >= sizeof (uint64_t )) {
51
+ crc = __crc32d (crc , * (uint64_t * )p );
52
+ p += sizeof (uint64_t );
53
+ nr -= sizeof (uint64_t );
54
+ }
55
+ if (nr >= sizeof (int32_t )) {
56
+ crc = __crc32w (crc , * (uint32_t * )p );
57
+ p += sizeof (uint32_t );
58
+ nr -= sizeof (uint32_t );
59
+ }
60
+ if (nr >= sizeof (int16_t )) {
61
+ crc = __crc32h (crc , * (uint16_t * )p );
62
+ p += sizeof (uint16_t );
63
+ nr -= sizeof (uint16_t );
64
+ }
65
+ if (nr ) {
66
+ crc = __crc32b (crc , * p );
67
+ }
68
+ return crc ;
69
+ }
70
+ # pragma GCC pop_options
47
71
#endif
48
72
49
73
/* {{{ proto string crc32(string str)
@@ -63,28 +87,11 @@ PHP_NAMED_FUNCTION(php_if_crc32)
63
87
64
88
#if defined(__aarch64__ )
65
89
if (has_crc32_insn ()) {
66
- while (nr >= sizeof (uint64_t )) {
67
- crc = __crc32d (crc , * (uint64_t * )p );
68
- p += sizeof (uint64_t );
69
- nr -= sizeof (uint64_t );
70
- }
71
- if (nr >= sizeof (int32_t )) {
72
- crc = __crc32w (crc , * (uint32_t * )p );
73
- p += sizeof (uint32_t );
74
- nr -= sizeof (uint32_t );
75
- }
76
- if (nr >= sizeof (int16_t )) {
77
- crc = __crc32h (crc , * (uint16_t * )p );
78
- p += sizeof (uint16_t );
79
- nr -= sizeof (uint16_t );
80
- }
81
- if (nr ) {
82
- crc = __crc32b (crc , * p );
83
- p += sizeof (uint8_t );
84
- nr -= sizeof (uint8_t );
85
- }
90
+ crc = crc32_aarch64 (crc , p , nr );
91
+ RETVAL_LONG (crc ^0xFFFFFFFF );
86
92
}
87
93
#endif
94
+
88
95
for (; nr -- ; ++ p ) {
89
96
crc = ((crc >> 8 ) & 0x00FFFFFF ) ^ crc32tab [(crc ^ (* p )) & 0xFF ];
90
97
}
0 commit comments