]> git.ipfire.org Git - thirdparty/zlib-ng.git/commitdiff
Improve performance of crc32_acle on 32-bit ARM
authorCameron Cawley <ccawley2011@gmail.com>
Wed, 11 Jan 2023 14:52:15 +0000 (14:52 +0000)
committerHans Kristian Rosbach <hk-github@circlestorm.org>
Thu, 21 Dec 2023 15:12:46 +0000 (16:12 +0100)
arch/arm/crc32_acle.c

index 0c9b9b6596f210e51fbe513fbe2bda75aac721db..978d97d720e61e7ae4f9c5059e22e4301760db7b 100644 (file)
@@ -17,34 +17,40 @@ Z_INTERNAL uint32_t crc32_acle(uint32_t crc, const uint8_t *buf, size_t len) {
     Z_REGISTER uint32_t c;
     Z_REGISTER const uint16_t *buf2;
     Z_REGISTER const uint32_t *buf4;
+    Z_REGISTER const uint64_t *buf8;
 
     c = ~crc;
-    if (len && ((ptrdiff_t)buf & 1)) {
-        c = __crc32b(c, *buf++);
-        len--;
-    }
-
-    if ((len >= sizeof(uint16_t)) && ((ptrdiff_t)buf & sizeof(uint16_t))) {
-        buf2 = (const uint16_t *) buf;
-        c = __crc32h(c, *buf2++);
-        len -= sizeof(uint16_t);
-        buf4 = (const uint32_t *) buf2;
-    } else {
-        buf4 = (const uint32_t *) buf;
-    }
 
-#if defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC)
-    if ((len >= sizeof(uint32_t)) && ((ptrdiff_t)buf & sizeof(uint32_t))) {
-        c = __crc32w(c, *buf4++);
-        len -= sizeof(uint32_t);
-    }
-
-    if (len == 0) {
+    if (UNLIKELY(len == 1)) {
+        c = __crc32b(c, *buf);
         c = ~c;
         return c;
     }
 
-    const uint64_t *buf8 = (const uint64_t *) buf4;
+    if ((ptrdiff_t)buf & (sizeof(uint64_t) - 1)) {
+        if (len && ((ptrdiff_t)buf & 1)) {
+            c = __crc32b(c, *buf++);
+            len--;
+        }
+
+        if ((len >= sizeof(uint16_t)) && ((ptrdiff_t)buf & sizeof(uint16_t))) {
+            buf2 = (const uint16_t *) buf;
+            c = __crc32h(c, *buf2++);
+            len -= sizeof(uint16_t);
+            buf4 = (const uint32_t *) buf2;
+        } else {
+            buf4 = (const uint32_t *) buf;
+        }
+
+        if ((len >= sizeof(uint32_t)) && ((ptrdiff_t)buf & sizeof(uint32_t))) {
+            c = __crc32w(c, *buf4++);
+            len -= sizeof(uint32_t);
+        }
+
+        buf8 = (const uint64_t *) buf4;
+    } else {
+        buf8 = (const uint64_t *) buf;
+    }
 
     while (len >= sizeof(uint64_t)) {
         c = __crc32d(c, *buf8++);
@@ -66,28 +72,6 @@ Z_INTERNAL uint32_t crc32_acle(uint32_t crc, const uint8_t *buf, size_t len) {
     }
 
     buf = (const unsigned char *) buf2;
-#else /* __aarch64__ */
-
-    if (len == 0) {
-        c = ~c;
-        return c;
-    }
-
-    while (len >= sizeof(uint32_t)) {
-        c = __crc32w(c, *buf4++);
-        len -= sizeof(uint32_t);
-    }
-
-    if (len >= sizeof(uint16_t)) {
-        buf2 = (const uint16_t *) buf4;
-        c = __crc32h(c, *buf2++);
-        len -= sizeof(uint16_t);
-        buf = (const unsigned char *) buf2;
-    } else {
-        buf = (const unsigned char *) buf4;
-    }
-#endif /* __aarch64__ */
-
     if (len) {
         c = __crc32b(c, *buf);
     }