summaryrefslogtreecommitdiff
path: root/ext/standard/crc32.c
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2019-10-02 14:41:25 +0200
committerNikita Popov <nikita.ppv@gmail.com>2019-10-02 14:41:25 +0200
commit8a2a9e05a4283b370d4293e7c28bc4ad32785ff7 (patch)
treedb20d4eda3c742dce0e65ffa33f44f752b27aad1 /ext/standard/crc32.c
parentd5e9ef8f0fad00618de62949d362d0980c6250f9 (diff)
parentd81eb77b4aaf579c151f7d16eef807838fcef9cc (diff)
downloadphp-git-8a2a9e05a4283b370d4293e7c28bc4ad32785ff7.tar.gz
Merge branch 'PHP-7.4'
Diffstat (limited to 'ext/standard/crc32.c')
-rw-r--r--ext/standard/crc32.c49
1 files changed, 28 insertions, 21 deletions
diff --git a/ext/standard/crc32.c b/ext/standard/crc32.c
index d82237daf1..8b556b3a34 100644
--- a/ext/standard/crc32.c
+++ b/ext/standard/crc32.c
@@ -19,7 +19,6 @@
#include "crc32.h"
#if defined(__aarch64__)
-# pragma GCC target ("+nothing+crc")
# include <arm_acle.h>
# if defined(__linux__)
# include <sys/auxv.h>
@@ -42,6 +41,31 @@ static inline int has_crc32_insn() {
return res;
# endif
}
+
+# pragma GCC push_options
+# pragma GCC target ("+nothing+crc")
+static uint32_t crc32_aarch64(uint32_t crc, char *p, size_t nr) {
+ while (nr >= sizeof(uint64_t)) {
+ crc = __crc32d(crc, *(uint64_t *)p);
+ p += sizeof(uint64_t);
+ nr -= sizeof(uint64_t);
+ }
+ if (nr >= sizeof(int32_t)) {
+ crc = __crc32w(crc, *(uint32_t *)p);
+ p += sizeof(uint32_t);
+ nr -= sizeof(uint32_t);
+ }
+ if (nr >= sizeof(int16_t)) {
+ crc = __crc32h(crc, *(uint16_t *)p);
+ p += sizeof(uint16_t);
+ nr -= sizeof(uint16_t);
+ }
+ if (nr) {
+ crc = __crc32b(crc, *p);
+ }
+ return crc;
+}
+# pragma GCC pop_options
#endif
/* {{{ proto string crc32(string str)
@@ -61,28 +85,11 @@ PHP_NAMED_FUNCTION(php_if_crc32)
#if defined(__aarch64__)
if (has_crc32_insn()) {
- while(nr >= sizeof(uint64_t)) {
- crc = __crc32d(crc, *(uint64_t *)p);
- p += sizeof(uint64_t);
- nr -= sizeof(uint64_t);
- }
- if (nr >= sizeof(int32_t)) {
- crc = __crc32w(crc, *(uint32_t *)p);
- p += sizeof(uint32_t);
- nr -= sizeof(uint32_t);
- }
- if (nr >= sizeof(int16_t)) {
- crc = __crc32h(crc, *(uint16_t *)p);
- p += sizeof(uint16_t);
- nr -= sizeof(uint16_t);
- }
- if (nr) {
- crc = __crc32b(crc, *p);
- p += sizeof(uint8_t);
- nr -= sizeof(uint8_t);
- }
+ crc = crc32_aarch64(crc, p, nr);
+ RETVAL_LONG(crc^0xFFFFFFFF);
}
#endif
+
for (; nr--; ++p) {
crc = ((crc >> 8) & 0x00FFFFFF) ^ crc32tab[(crc ^ (*p)) & 0xFF ];
}