]> git.ipfire.org Git - thirdparty/zlib-ng.git/commitdiff
Use index-based CRC macros and inline memcpy.
authorNathan Moinvaziri <nathan@nathanm.com>
Mon, 26 Jan 2026 22:53:43 +0000 (14:53 -0800)
committerHans Kristian Rosbach <hk-github@circlestorm.org>
Thu, 29 Jan 2026 12:29:39 +0000 (13:29 +0100)
arch/generic/crc32_braid_c.c
arch/x86/crc32_pclmulqdq_tpl.h
crc32_p.h

index 0082770153b6c2a53f5e7790d512df3dcd955eb4..36f5dce92f12ca91492fa41ccc43faf5f7404082 100644 (file)
@@ -72,9 +72,11 @@ Z_INTERNAL uint32_t crc32_braid_internal(uint32_t c, const uint8_t *buf, size_t
 
         /* Compute the CRC up to a z_word_t boundary. */
         size_t align_diff = (size_t)MIN(ALIGN_DIFF(buf, BRAID_W), len);
-        len -= align_diff;
-        while (align_diff--)
-            CRC_DO1;
+        if (align_diff) {
+            c = crc32_copy_small(c, NULL, buf, align_diff, BRAID_W - 1, 0);
+            len -= align_diff;
+            buf += align_diff;
+        }
 
         /* Compute the CRC on as many BRAID_N z_word_t blocks as are available. */
         blks = len / (BRAID_N * BRAID_W);
@@ -200,7 +202,7 @@ Z_INTERNAL uint32_t crc32_braid_internal(uint32_t c, const uint8_t *buf, size_t
 #endif /* BRAID_W */
 
     /* Complete the computation of the CRC on any remaining bytes. */
-    return crc32_copy_small(c, NULL, buf, len, 0);
+    return crc32_copy_small(c, NULL, buf, len, (BRAID_N * BRAID_W) - 1, 0);
 }
 
 Z_INTERNAL uint32_t crc32_braid(uint32_t crc, const uint8_t *buf, size_t len) {
index 701b0feeb678d48885aee99e2b2c37713d152bcd..b7ed17f809918426c643aedc5d4ddaf7a5de7e4a 100644 (file)
@@ -149,7 +149,7 @@ Z_FORCEINLINE static uint32_t crc32_copy_impl(uint32_t crc, uint8_t *dst, const
     }
 
     if (copy_len > 0) {
-        crc = crc32_copy_small(~crc, dst, src, copy_len, COPY);
+        crc = ~crc32_copy_small(~crc, dst, src, copy_len, 31, COPY);
         src += copy_len;
         len -= copy_len;
         if (COPY) {
index 8f1d1d06c338a4d95ea2e9ea06a24f7f1adf3dff..397464a446d8596084baf10bb1001720e460ab45 100644 (file)
--- a/crc32_p.h
+++ b/crc32_p.h
@@ -1,30 +1,54 @@
 /* crc32_p.h -- Private inline functions and macros shared with
  *              different computation of the CRC-32 checksum
  *              of a data stream.
- * Copyright (C) 1995-2011, 2016 Mark Adler
+ * Copyright (C) 2026 Nathan Moinvaziri
  * For conditions of distribution and use, see copyright notice in zlib.h
  */
 
 #ifndef CRC32_P_H
 #define CRC32_P_H
 
-#define CRC_DO1 c = crc_table[(c ^ *buf++) & 0xff] ^ (c >> 8)
-#define CRC_DO8 CRC_DO1; CRC_DO1; CRC_DO1; CRC_DO1; CRC_DO1; CRC_DO1; CRC_DO1; CRC_DO1
+#define CRC_DO1(c, buf, i) c = crc_table[(c ^ buf[i]) & 0xff] ^ (c >> 8)
+#define CRC_DO2(c, buf, i) {CRC_DO1(c, buf, i); CRC_DO1(c, buf, i+1);}
+#define CRC_DO4(c, buf, i) {CRC_DO2(c, buf, i); CRC_DO2(c, buf, i+2);}
+#define CRC_DO8(c, buf, i) {CRC_DO4(c, buf, i); CRC_DO4(c, buf, i+4);}
 
-Z_FORCEINLINE static uint32_t crc32_copy_small(uint32_t crc, uint8_t *dst, const uint8_t *buf, size_t len, const int COPY) {
-    uint32_t c = crc;
-    if (COPY) {
-        memcpy(dst, buf, len);
+Z_FORCEINLINE static uint32_t crc32_copy_small(uint32_t crc, uint8_t *dst, const uint8_t *buf, size_t len,
+                                               const int MAX_LEN, const int COPY) {
+    if (MAX_LEN >= 8) {
+        while (len >= 8) {
+            if (COPY) {
+                memcpy(dst, buf, 8);
+                dst += 8;
+            }
+            CRC_DO8(crc, buf, 0);
+            buf += 8;
+            len -= 8;
+        }
     }
-    while (len >= 8) {
-        len -= 8;
-        CRC_DO8;
+    if (len & 4) {
+        if (COPY) {
+            memcpy(dst, buf, 4);
+            dst += 4;
+        }
+        CRC_DO4(crc, buf, 0);
+        buf += 4;
     }
-    while (len--) {
-        CRC_DO1;
+    if (len & 2) {
+        if (COPY) {
+            memcpy(dst, buf, 2);
+            dst += 2;
+        }
+        CRC_DO2(crc, buf, 0);
+        buf += 2;
+    }
+    if (len & 1) {
+        if (COPY)
+            *dst = *buf;
+        CRC_DO1(crc, buf, 0);
     }
 
-    return ~c;
+    return crc;
 }
 
 #endif /* CRC32_P_H */