diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2019-10-02 14:41:25 +0200 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2019-10-02 14:41:25 +0200 |
commit | 8a2a9e05a4283b370d4293e7c28bc4ad32785ff7 (patch) | |
tree | db20d4eda3c742dce0e65ffa33f44f752b27aad1 /ext/standard/crc32.c | |
parent | d5e9ef8f0fad00618de62949d362d0980c6250f9 (diff) | |
parent | d81eb77b4aaf579c151f7d16eef807838fcef9cc (diff) | |
download | php-git-8a2a9e05a4283b370d4293e7c28bc4ad32785ff7.tar.gz |
Merge branch 'PHP-7.4'
Diffstat (limited to 'ext/standard/crc32.c')
-rw-r--r-- | ext/standard/crc32.c | 49 |
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 ]; } |