]> git.ipfire.org Git - thirdparty/zlib-ng.git/commitdiff
Add ALIGN_DIFF to perform alignment needed to next boundary
authorNathan Moinvaziri <nathan@nathanm.com>
Sun, 4 Jan 2026 07:52:27 +0000 (23:52 -0800)
committerHans Kristian Rosbach <hk-github@circlestorm.org>
Tue, 6 Jan 2026 23:19:32 +0000 (00:19 +0100)
arch/generic/crc32_braid_c.c
arch/generic/crc32_chorba_c.c
arch/power/adler32_vmx.c
arch/power/crc32_power8.c
arch/s390/crc32-vx.c
arch/x86/chorba_sse2.c
arch/x86/chorba_sse41.c
arch/x86/crc32_pclmulqdq_tpl.h
zbuild.h
zutil.c

index 71f2ac43fb16f0f487cbb109594a9dda49c53e96..3b447ed9c0342488a70852aa71b55dd1551be04e 100644 (file)
@@ -70,10 +70,10 @@ Z_INTERNAL uint32_t crc32_braid_internal(uint32_t c, const uint8_t *buf, size_t
         int k;
 
         /* Compute the CRC up to a z_word_t boundary. */
-        while (len && ((uintptr_t)buf & (BRAID_W - 1)) != 0) {
-            len--;
+        size_t align_diff = (size_t)MIN(ALIGN_DIFF(buf, BRAID_W), len);
+        len -= align_diff;
+        while (align_diff--)
             CRC_DO1;
-        }
 
         /* Compute the CRC on as many BRAID_N z_word_t blocks as are available. */
         blks = len / (BRAID_N * BRAID_W);
index 303a516a0b4876efc6df6769320a6d01c22e7346..9455b55eedf1687e186ca5e46ebaa8ba1b83139b 100644 (file)
@@ -1448,27 +1448,27 @@ Z_INTERNAL uint32_t crc32_chorba_small_nondestructive_32bit (uint32_t crc, const
 #endif // OPTIMAL_CMP == 64
 
 Z_INTERNAL uint32_t crc32_chorba(uint32_t crc, const uint8_t *buf, size_t len) {
-    uint64_taligned_buf;
+    uint64_t *aligned_buf;
     uint32_t c = (~crc) & 0xffffffff;
-    uintptr_t algn_diff = ((uintptr_t)8 - ((uintptr_t)buf & 7)) & 7;
+    uintptr_t align_diff = ALIGN_DIFF(buf, 8);
 
-    if (len > algn_diff + CHORBA_SMALL_THRESHOLD) {
-        if (algn_diff) {
-            c = crc32_braid_internal(c, buf, algn_diff);
-            len -= algn_diff;
+    if (len > align_diff + CHORBA_SMALL_THRESHOLD) {
+        if (align_diff) {
+            c = crc32_braid_internal(c, buf, align_diff);
+            len -= align_diff;
         }
-        aligned_buf = (uint64_t*) (buf + algn_diff);
+        aligned_buf = (uint64_t*)(buf + align_diff);
         if(len > CHORBA_LARGE_THRESHOLD) {
-            c = crc32_chorba_118960_nondestructive(c, (z_word_t*) aligned_buf, len);
+            c = crc32_chorba_118960_nondestructive(c, (z_word_t*)aligned_buf, len);
 #  if OPTIMAL_CMP == 64
         } else if (len > CHORBA_MEDIUM_LOWER_THRESHOLD && len <= CHORBA_MEDIUM_UPPER_THRESHOLD) {
-            c = crc32_chorba_32768_nondestructive(c, (uint64_t*) aligned_buf, len);
+            c = crc32_chorba_32768_nondestructive(c, (uint64_t*)aligned_buf, len);
 #  endif
         } else {
 #  if OPTIMAL_CMP == 64
-            c = crc32_chorba_small_nondestructive(c, (uint64_t*) aligned_buf, len);
+            c = crc32_chorba_small_nondestructive(c, (uint64_t*)aligned_buf, len);
 #  else
-            c = crc32_chorba_small_nondestructive_32bit(c, (uint32_t*) aligned_buf, len);
+            c = crc32_chorba_small_nondestructive_32bit(c, (uint32_t*)aligned_buf, len);
 #  endif
         }
     } else {
index 004d3fce686e6e1da7d3c71a2c4af7c400e0525d..0478d052d79bbdee05ab87b75d005406bc6fae2b 100644 (file)
@@ -123,7 +123,7 @@ static inline uint32_t adler32_impl(uint32_t adler, const uint8_t *buf, size_t l
     uint32_t pair[16] ALIGNED_(16);
     memset(&pair[2], 0, 14);
     int n = NMAX;
-    unsigned int done = 0, i;
+    unsigned int done = 0;
 
     /* Split Adler-32 into component sums, it can be supplied by
      * the caller sites (e.g. in a PNG file).
@@ -146,23 +146,17 @@ static inline uint32_t adler32_impl(uint32_t adler, const uint8_t *buf, size_t l
         return adler32_copy_len_16(adler, NULL, buf, len, sum2, 0);
 
     // Align buffer
-    unsigned int al = 0;
-    if ((uintptr_t)buf & 0xf) {
-        al = 16-((uintptr_t)buf & 0xf);
-        if (al > len) {
-            al=len;
-        }
-        vmx_handle_head_or_tail(pair, buf, al);
-
-        done += al;
+    size_t align_len = (size_t)MIN(ALIGN_DIFF(buf, 16), len);
+    if (align_len) {
+        vmx_handle_head_or_tail(pair, buf, align_len);
+        done += align_len;
         /* Rather than rebasing, we can reduce the max sums for the
          * first round only */
-        n -= al;
+        n -= align_len;
     }
-    for (i = al; i < len; i += n) {
+    for (size_t i = align_len; i < len; i += n) {
         int remaining = (int)(len-i);
-        n = MIN(remaining, (i == al) ? n : NMAX);
-
+        n = MIN(remaining, (i == align_len) ? n : NMAX);
         if (n < 16)
             break;
 
index 20ea89ed2169cdea326b653a770effdfb89e8256..914cca8ab2c7e28f97d68ef53c0b1ad49099cc7b 100644 (file)
@@ -63,7 +63,7 @@ Z_INTERNAL uint32_t crc32_power8(uint32_t crc, const unsigned char *p, size_t _l
     }
 
     if ((unsigned long)p & VMX_ALIGN_MASK) {
-        prealign = VMX_ALIGN - ((unsigned long)p & VMX_ALIGN_MASK);
+        prealign = (unsigned int)ALIGN_DIFF(p, VMX_ALIGN);
         crc = crc32_align(crc, p, prealign);
         len -= prealign;
         p += prealign;
index 10105990de0bea33226747e4d9cb6c101f0d50fb..c1de8b6f85818a2e40e57e4c1f1143df2f2843ef 100644 (file)
@@ -205,7 +205,7 @@ uint32_t Z_INTERNAL crc32_s390_vx(uint32_t crc, const unsigned char *buf, size_t
         return crc32_braid(crc, buf, len);
 
     if ((uintptr_t)buf & VX_ALIGN_MASK) {
-        prealign = VX_ALIGNMENT - ((uintptr_t)buf & VX_ALIGN_MASK);
+        prealign = (size_t)ALIGN_DIFF(buf, VX_ALIGNMENT);
         len -= prealign;
         crc = crc32_braid(crc, buf, prealign);
         buf += prealign;
index 95da8e99b72a6056c2263f493d8cebb5e47d15b1..a5567faf3b4e58f0fe0e8446af672dbf20262644 100644 (file)
@@ -847,19 +847,19 @@ Z_INTERNAL uint32_t chorba_small_nondestructive_sse2(uint32_t crc, const uint64_
 }
 
 Z_INTERNAL uint32_t crc32_chorba_sse2(uint32_t crc, const uint8_t *buf, size_t len) {
-    uint64_taligned_buf;
+    uint64_t *aligned_buf;
     uint32_t c = (~crc) & 0xffffffff;
-    uintptr_t algn_diff = ((uintptr_t)16 - ((uintptr_t)buf & 15)) & 15;
+    uintptr_t align_diff = ALIGN_DIFF(buf, 16);
 
-    if (len > algn_diff + CHORBA_SMALL_THRESHOLD_64BIT) {
-        if (algn_diff) {
-            c = crc32_braid_internal(c, buf, algn_diff);
-            len -= algn_diff;
+    if (len > align_diff + CHORBA_SMALL_THRESHOLD_64BIT) {
+        if (align_diff) {
+            c = crc32_braid_internal(c, buf, align_diff);
+            len -= align_diff;
         }
-        aligned_buf = (uint64_t*) (buf + algn_diff);
+        aligned_buf = (uint64_t*)(buf + align_diff);
 #if !defined(WITHOUT_CHORBA)
-        if(len > CHORBA_LARGE_THRESHOLD) {
-            c = crc32_chorba_118960_nondestructive(c, (z_word_t*) aligned_buf, len);
+        if (len > CHORBA_LARGE_THRESHOLD) {
+            c = crc32_chorba_118960_nondestructive(c, (z_word_t*)aligned_buf, len);
         } else
 #endif
         {
index 9f2b65a3ef9afdce01b42920fe09ca7508f03c6f..07daf70947892dbb1e13dddb3780f5ed2d9db20e 100644 (file)
@@ -305,19 +305,19 @@ static Z_FORCEINLINE uint32_t crc32_chorba_32768_nondestructive_sse41(uint32_t c
 }
 
 Z_INTERNAL uint32_t crc32_chorba_sse41(uint32_t crc, const uint8_t *buf, size_t len) {
-    uint64_taligned_buf;
+    uint64_t *aligned_buf;
     uint32_t c = (~crc) & 0xffffffff;
-    uintptr_t algn_diff = ((uintptr_t)16 - ((uintptr_t)buf & 15)) & 15;
+    uintptr_t align_diff = ALIGN_DIFF(buf, 16);
 
-    if (len > algn_diff + CHORBA_SMALL_THRESHOLD_64BIT) {
-        if (algn_diff) {
-            c = crc32_braid_internal(c, buf, algn_diff);
-            len -= algn_diff;
+    if (len > align_diff + CHORBA_SMALL_THRESHOLD_64BIT) {
+        if (align_diff) {
+            c = crc32_braid_internal(c, buf, align_diff);
+            len -= align_diff;
         }
-        aligned_buf = (uint64_t*) (buf + algn_diff);
+        aligned_buf = (uint64_t*)(buf + align_diff);
 #if !defined(WITHOUT_CHORBA)
-        if(len > CHORBA_LARGE_THRESHOLD) {
-            c = crc32_chorba_118960_nondestructive(c, (z_word_t*) aligned_buf, len);
+        if (len > CHORBA_LARGE_THRESHOLD) {
+            c = crc32_chorba_118960_nondestructive(c, (z_word_t*)aligned_buf, len);
         } else
 #endif
         if (len > CHORBA_MEDIUM_LOWER_THRESHOLD && len <= CHORBA_MEDIUM_UPPER_THRESHOLD) {
index 079c22e05892a942790ad3b06d443f9b3164a5e5..fc35b449cf90e91c09f1f924b02d2ef21822956d 100644 (file)
@@ -337,11 +337,11 @@ Z_FORCEINLINE static uint32_t crc32_copy_impl(uint32_t crc, uint8_t *dst, const
     size_t copy_len = len;
     if (len >= 16) {
         /* Calculate 16-byte alignment offset */
-        unsigned algn_diff = ((uintptr_t)16 - ((uintptr_t)src & 0xF)) & 0xF;
+        uintptr_t align_diff = ALIGN_DIFF(src, 16);
 
         /* If total length is less than (alignment bytes + 16), use the faster small method.
          * Handles both initially small buffers and cases where alignment would leave < 16 bytes */
-        copy_len = len < algn_diff + 16 ? len : algn_diff;
+        copy_len = len < align_diff + 16 ? len : align_diff;
     }
 
     if (copy_len > 0) {
index 7db64e5b46898fedf33ac344d990e16deaca7998..1354cc9450060a76e6365c8e1bd372fcce234a8e 100644 (file)
--- a/zbuild.h
+++ b/zbuild.h
 #define HINT_ALIGNED_64(p) HINT_ALIGNED((p),64)
 #define HINT_ALIGNED_4096(p) HINT_ALIGNED((p),4096)
 
+/* Number of bytes needed to align ptr to the next alignment boundary */
+#define ALIGN_DIFF(ptr, align) \
+    (((uintptr_t)(align) - ((uintptr_t)(ptr) & ((align) - 1))) & ((align) - 1))
+
 /* PADSZ returns needed bytes to pad bpos to pad size
  * PAD_NN calculates pad size and adds it to bpos, returning the result.
  * All take an integer or a pointer as bpos input.
diff --git a/zutil.c b/zutil.c
index e77bf1aea179a0c30a349fe3486fc1080feb8c1f..937c83da4482f058d087796a5849dcc9fd637fd5 100644 (file)
--- a/zutil.c
+++ b/zutil.c
@@ -114,8 +114,8 @@ void Z_INTERNAL PREFIX(zcfree)(void *opaque, void *ptr) {
 
 /* Provide aligned allocations, only used by gz* code */
 void Z_INTERNAL *zng_alloc_aligned(unsigned size, unsigned align) {
-    uintptr_t return_ptr, original_ptr;
-    uint32_t alloc_size, align_diff;
+    uintptr_t return_ptr, original_ptr, align_diff;
+    uint32_t alloc_size;
     void *ptr;
 
     /* Allocate enough memory for proper alignment and to store the original memory pointer */
@@ -125,7 +125,7 @@ void Z_INTERNAL *zng_alloc_aligned(unsigned size, unsigned align) {
         return NULL;
 
     /* Calculate return pointer address with space enough to store original pointer */
-    align_diff = align - ((uintptr_t)ptr % align);
+    align_diff = ALIGN_DIFF(ptr, align);
     return_ptr = (uintptr_t)ptr + align_diff;
     if (align_diff < sizeof(void *))
         return_ptr += align;