]> git.ipfire.org Git - thirdparty/zlib-ng.git/commitdiff
Make CRC32 checking of headers use crc32_small directly, instead of taking
authorHans Kristian Rosbach <hk-git@circlestorm.org>
Thu, 14 May 2026 11:06:45 +0000 (13:06 +0200)
committerHans Kristian Rosbach <hk-github@circlestorm.org>
Sat, 16 May 2026 23:36:02 +0000 (01:36 +0200)
a detour through functable to spin up a vector optimized function when the
header is too small to be handled by it.
CRC2 and CRC4 call CRC_DO1_B macro directly since knowing the exact size
lets us inline a very small crc implementation.

arch/generic/generic_functions.h
crc32.c
crc32_p.h
deflate.c
inflate.c
inflate_p.h

index a01778b71837da173b65dbaa0cf56edbef006055..cfe94075322c1652a992188a341143fb2a567a43 100644 (file)
@@ -12,6 +12,8 @@ typedef uint32_t (*crc32_func)(uint32_t crc, const uint8_t *buf, size_t len);
 typedef uint32_t (*crc32_copy_func)(uint32_t crc, uint8_t *dst, const uint8_t *src, size_t len);
 typedef void     (*slide_hash_func)(deflate_state *s);
 
+uint32_t crc32_small(uint32_t crc, const uint8_t *buf, size_t len);
+
 #ifdef ADLER32_FALLBACK
 uint32_t adler32_c(uint32_t adler, const uint8_t *buf, size_t len);
 uint32_t adler32_copy_c(uint32_t adler, uint8_t *dst, const uint8_t *src, size_t len);
diff --git a/crc32.c b/crc32.c
index e31fff62aff82543da6e2daae04020716743f85e..cbc9ef0226f95f527917926300c28a43f7b1daae 100644 (file)
--- a/crc32.c
+++ b/crc32.c
@@ -9,7 +9,7 @@
 
 #include "zbuild.h"
 #include "functable.h"
-#include "crc32_braid_tbl.h"
+#include "crc32_p.h"
 
 /* ========================================================================= */
 
@@ -17,6 +17,15 @@ const uint32_t * Z_EXPORT PREFIX(get_crc_table)(void) {
     return (const uint32_t *)crc_table;
 }
 
+/* crc32 function meant for short buffers like gzip headers */
+Z_INTERNAL uint32_t crc32_small(uint32_t crc, const uint8_t *buf, size_t len) {
+    if (UNLIKELY(len >= 32)){
+        return FUNCTABLE_CALL(crc32)(crc, buf, len);
+    }
+
+    return ~crc32_copy_small(~crc, NULL, buf, len, 32, 0);
+}
+
 #ifdef ZLIB_COMPAT
 unsigned long Z_EXPORT PREFIX(crc32_z)(unsigned long crc, const unsigned char *buf, size_t len) {
     if (buf == NULL)
index 397464a446d8596084baf10bb1001720e460ab45..4b097deb3752463af0bc9f082ed908855f7c093b 100644 (file)
--- a/crc32_p.h
+++ b/crc32_p.h
@@ -8,6 +8,8 @@
 #ifndef CRC32_P_H
 #define CRC32_P_H
 
+#include "crc32_braid_tbl.h"
+
 #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);}
index a0256cb01a4cd6a5762ec72b8d5e586227a33a1f..6883a2137dd186a41ac25e5fb2f8448823edb012 100644 (file)
--- a/deflate.c
+++ b/deflate.c
@@ -52,6 +52,7 @@
 #include "deflate.h"
 #include "deflate_p.h"
 #include "insert_string_p.h"
+#include "arch_functions.h"
 
 /* Avoid conflicts with zlib.h macros */
 #ifdef ZLIB_COMPAT
@@ -754,7 +755,7 @@ Z_INTERNAL void PREFIX(flush_pending)(PREFIX3(stream) *strm) {
 #define HCRC_UPDATE(beg) \
     do { \
         if (s->gzhead->hcrc && s->pending > (beg)) \
-            strm->adler = PREFIX(crc32)(strm->adler, s->pending_buf + (beg), s->pending - (beg)); \
+            strm->adler = crc32_small((uint32_t)strm->adler, s->pending_buf + (beg), s->pending - (beg)); \
     } while (0)
 
 /* ========================================================================= */
@@ -874,7 +875,7 @@ int32_t Z_EXPORT PREFIX(deflate)(PREFIX3(stream) *strm, int32_t flush) {
             if (s->gzhead->extra != NULL)
                 put_short(s, (uint16_t)s->gzhead->extra_len);
             if (s->gzhead->hcrc)
-                strm->adler = PREFIX(crc32)(strm->adler, s->pending_buf, s->pending);
+                strm->adler = crc32_small((uint32_t)strm->adler, s->pending_buf, s->pending);
             s->gzindex = 0;
             s->status = EXTRA_STATE;
         }
index 5707082d6e682027472fb4b7fa15ddad5efd1929..cd75068cdb7161bdc610d554d53d3900da5ee810 100644 (file)
--- a/inflate.c
+++ b/inflate.c
@@ -11,6 +11,7 @@
 #include "inflate_p.h"
 #include "inffixed_tbl.h"
 #include "functable.h"
+#include "arch_functions.h"
 
 /* Avoid conflicts with zlib.h macros */
 #ifdef ZLIB_COMPAT
@@ -624,7 +625,7 @@ int32_t Z_EXPORT PREFIX(inflate)(PREFIX3(stream) *strm, int32_t flush) {
                         }
                     }
                     if ((state->flags & 0x0200) && (state->wrap & 4)) {
-                        state->check = PREFIX(crc32)(state->check, next, copy);
+                        state->check = crc32_small((uint32_t)state->check, next, copy);
                     }
                     have -= copy;
                     next += copy;
@@ -647,7 +648,7 @@ int32_t Z_EXPORT PREFIX(inflate)(PREFIX3(stream) *strm, int32_t flush) {
                         state->head->name[state->length++] = (unsigned char)len;
                 } while (len && copy < have);
                 if ((state->flags & 0x0200) && (state->wrap & 4))
-                    state->check = PREFIX(crc32)(state->check, next, copy);
+                    state->check = crc32_small((uint32_t)state->check, next, copy);
                 have -= copy;
                 next += copy;
                 if (len)
@@ -670,7 +671,7 @@ int32_t Z_EXPORT PREFIX(inflate)(PREFIX3(stream) *strm, int32_t flush) {
                         state->head->comment[state->length++] = (unsigned char)len;
                 } while (len && copy < have);
                 if ((state->flags & 0x0200) && (state->wrap & 4))
-                    state->check = PREFIX(crc32)(state->check, next, copy);
+                    state->check = crc32_small((uint32_t)state->check, next, copy);
                 have -= copy;
                 next += copy;
                 if (len)
index cd9e1f214cbe330b681a3fcfbffdabb0302161c7..ee91d194ada6dce7e8bc561d78fe6cc5e18996f7 100644 (file)
@@ -9,6 +9,7 @@
 
 #include "zendian.h"
 #include "zmemory.h"
+#include "crc32_braid_tbl.h"
 
 /* Architecture-specific hooks. */
 #ifdef S390_DFLTCC_INFLATE
  *   Macros shared by inflate() and inflateBack()
  */
 
-/* check function to use adler32() for zlib or crc32() for gzip */
-#ifdef GUNZIP
-#  define UPDATE(check, buf, len) \
-    (state->flags ? PREFIX(crc32)(check, buf, len) : FUNCTABLE_CALL(adler32)(check, buf, len))
-#else
-#  define UPDATE(check, buf, len) FUNCTABLE_CALL(adler32)(check, buf, len)
-#endif
-
 /* check macros for header crc */
 #ifdef GUNZIP
+#  define CRC_DO1_B(c, b)    c = crc_table[(c ^ (b)) & 0xff] ^ (c >> 8)
+
 #  define CRC2(check, word) \
     do { \
-        uint16_t tmp = Z_U16_TO_LE((uint16_t)(word)); \
-        check = PREFIX(crc32)(check, (const unsigned char *)&tmp, 2); \
+        uint32_t crc = ~(uint32_t)(check); \
+        CRC_DO1_B(crc, (word)     ); \
+        CRC_DO1_B(crc, (word) >> 8); \
+        (check) = ~crc; \
     } while (0)
 
 #  define CRC4(check, word) \
     do { \
-        uint32_t tmp = Z_U32_TO_LE((uint32_t)(word)); \
-        check = PREFIX(crc32)(check, (const unsigned char *)&tmp, 4); \
+        uint32_t crc = ~(uint32_t)(check); \
+        CRC_DO1_B(crc, (word)      ); \
+        CRC_DO1_B(crc, (word) >>  8); \
+        CRC_DO1_B(crc, (word) >> 16); \
+        CRC_DO1_B(crc, (word) >> 24); \
+        (check) = ~crc; \
     } while (0)
 #endif