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