]> git.ipfire.org Git - thirdparty/zlib-ng.git/commitdiff
Use memcpy for unaligned reads.
authorNathan Moinvaziri <nathan@nathanm.com>
Mon, 27 Dec 2021 03:56:12 +0000 (19:56 -0800)
committerHans Kristian Rosbach <hk-github@circlestorm.org>
Sat, 8 Jan 2022 13:33:19 +0000 (14:33 +0100)
Co-authored-by: Matija Skala <mskala@gmx.com>
chunkset.c
compare258.c
deflate.h
insert_string_tpl.h
match_tpl.h

index b07e6f482710f45a4af8d63bddb2c53cd95562ce..48cdd9df6f0e44be1d8c5daef1eb7505630c4a3d 100644 (file)
@@ -5,7 +5,7 @@
 #include "zbuild.h"
 #include "zutil.h"
 
-// We need sizeof(chunk_t) to be 8, no matter what.
+/* Define 8 byte chunks differently depending on unaligned support */
 #if defined(UNALIGNED64_OK)
 typedef uint64_t chunk_t;
 #elif defined(UNALIGNED_OK)
@@ -34,27 +34,24 @@ static inline void chunkmemset_1(uint8_t *from, chunk_t *chunk) {
 static inline void chunkmemset_4(uint8_t *from, chunk_t *chunk) {
 #if defined(UNALIGNED64_OK)
     uint32_t half_chunk;
-    half_chunk = *(uint32_t *)from;
+    memcpy(&half_chunk, from, sizeof(half_chunk));
     *chunk = 0x0000000100000001 * (uint64_t)half_chunk;
 #elif defined(UNALIGNED_OK)
-    chunk->u32[0] = *(uint32_t *)from;
+    memcpy(&chunk->u32[0], from, sizeof(chunk->u32[0]));
     chunk->u32[1] = chunk->u32[0];
 #else
     uint8_t *chunkptr = (uint8_t *)chunk;
-    memcpy(chunkptr, from, 4);
-    memcpy(chunkptr+4, from, 4);
+    memcpy(chunkptr, from, sizeof(uint32_t));
+    memcpy(chunkptr+4, from, sizeof(uint32_t));
 #endif
 }
 
 static inline void chunkmemset_8(uint8_t *from, chunk_t *chunk) {
-#if defined(UNALIGNED64_OK)
-    *chunk = *(uint64_t *)from;
-#elif defined(UNALIGNED_OK)
-    uint32_t* p = (uint32_t *)from;
-    chunk->u32[0] = p[0];
-    chunk->u32[1] = p[1];
+#if defined(UNALIGNED_OK) && !defined(UNALIGNED64_OK)
+    memcpy(&chunk->u32[0], from, sizeof(chunk->u32[0]));
+    memcpy(&chunk->u32[1], from+4, sizeof(chunk->u32[1]));
 #else
-    memcpy(chunk, from, sizeof(chunk_t));
+    memcpy(chunk, from, sizeof(uint64_t));
 #endif
 }
 
@@ -63,14 +60,7 @@ static inline void loadchunk(uint8_t const *s, chunk_t *chunk) {
 }
 
 static inline void storechunk(uint8_t *out, chunk_t *chunk) {
-#if defined(UNALIGNED64_OK)
-    *(uint64_t *)out = *chunk;
-#elif defined(UNALIGNED_OK)
-    ((uint32_t *)out)[0] = chunk->u32[0];
-    ((uint32_t *)out)[1] = chunk->u32[1];
-#else
-    memcpy(out, chunk, sizeof(chunk_t));
-#endif
+    memcpy(out, chunk, sizeof(uint64_t));
 }
 
 #define CHUNKSIZE        chunksize_c
index f4f1936c45710faecaad39d509a7b10254731797..e6e63f249e4aed830ed0bf672533feeab3e2671c 100644 (file)
@@ -123,10 +123,12 @@ static inline uint32_t compare256_unaligned_32_static(const unsigned char *src0,
     uint32_t len = 0;
 
     do {
-        uint32_t sv = *(uint32_t *)src0;
-        uint32_t mv = *(uint32_t *)src1;
-        uint32_t diff = sv ^ mv;
+        uint32_t sv, mv, diff;
 
+        memcpy(&sv, src0, sizeof(sv));
+        memcpy(&mv, src1, sizeof(mv));
+
+        diff = sv ^ mv;
         if (diff) {
             uint32_t match_byte = __builtin_ctz(diff) / 8;
             return len + match_byte;
@@ -170,10 +172,12 @@ static inline uint32_t compare256_unaligned_64_static(const unsigned char *src0,
     uint32_t len = 0;
 
     do {
-        uint64_t sv = *(uint64_t *)src0;
-        uint64_t mv = *(uint64_t *)src1;
-        uint64_t diff = sv ^ mv;
+        uint64_t sv, mv, diff;
+
+        memcpy(&sv, src0, sizeof(sv));
+        memcpy(&mv, src1, sizeof(mv));
 
+        diff = sv ^ mv;
         if (diff) {
             uint64_t match_byte = __builtin_ctzll(diff) / 8;
             return len + (uint32_t)match_byte;
index 94ff239ce4bbc1894744cdc9291fe2826b8fec42..030db4f098d921fd2852963f1fdd26a5a8fa1d96 100644 (file)
--- a/deflate.h
+++ b/deflate.h
@@ -302,13 +302,11 @@ typedef enum {
  * IN assertion: there is enough room in pending_buf.
  */
 static inline void put_short(deflate_state *s, uint16_t w) {
-#if defined(UNALIGNED_OK)
-    *(uint16_t *)(&s->pending_buf[s->pending]) = w;
-    s->pending += 2;
-#else
-    put_byte(s, (w & 0xff));
-    put_byte(s, ((w >> 8) & 0xff));
+#if BYTE_ORDER == BIG_ENDIAN
+    w = ZSWAP16(w);
 #endif
+    memcpy(&s->pending_buf[s->pending], &w, sizeof(w));
+    s->pending += 2;
 }
 
 /* ===========================================================================
@@ -316,8 +314,11 @@ static inline void put_short(deflate_state *s, uint16_t w) {
  * IN assertion: there is enough room in pending_buf.
  */
 static inline void put_short_msb(deflate_state *s, uint16_t w) {
-    put_byte(s, ((w >> 8) & 0xff));
-    put_byte(s, (w & 0xff));
+#if BYTE_ORDER == LITTLE_ENDIAN
+    w = ZSWAP16(w);
+#endif
+    memcpy(&s->pending_buf[s->pending], &w, sizeof(w));
+    s->pending += 2;
 }
 
 /* ===========================================================================
@@ -325,15 +326,11 @@ static inline void put_short_msb(deflate_state *s, uint16_t w) {
  * IN assertion: there is enough room in pending_buf.
  */
 static inline void put_uint32(deflate_state *s, uint32_t dw) {
-#if defined(UNALIGNED_OK)
-    *(uint32_t *)(&s->pending_buf[s->pending]) = dw;
-    s->pending += 4;
-#else
-    put_byte(s, (dw & 0xff));
-    put_byte(s, ((dw >> 8) & 0xff));
-    put_byte(s, ((dw >> 16) & 0xff));
-    put_byte(s, ((dw >> 24) & 0xff));
+#if BYTE_ORDER == BIG_ENDIAN
+    dw = ZSWAP32(dw);
 #endif
+    memcpy(&s->pending_buf[s->pending], &dw, sizeof(dw));
+    s->pending += 4;
 }
 
 /* ===========================================================================
@@ -341,15 +338,11 @@ static inline void put_uint32(deflate_state *s, uint32_t dw) {
  * IN assertion: there is enough room in pending_buf.
  */
 static inline void put_uint32_msb(deflate_state *s, uint32_t dw) {
-#if defined(UNALIGNED_OK)
-    *(uint32_t *)(&s->pending_buf[s->pending]) = ZSWAP32(dw);
-    s->pending += 4;
-#else
-    put_byte(s, ((dw >> 24) & 0xff));
-    put_byte(s, ((dw >> 16) & 0xff));
-    put_byte(s, ((dw >> 8) & 0xff));
-    put_byte(s, (dw & 0xff));
+#if BYTE_ORDER == LITTLE_ENDIAN
+    dw = ZSWAP32(dw);
 #endif
+    memcpy(&s->pending_buf[s->pending], &dw, sizeof(dw));
+    s->pending += 4;
 }
 
 /* ===========================================================================
@@ -357,24 +350,11 @@ static inline void put_uint32_msb(deflate_state *s, uint32_t dw) {
  * IN assertion: there is enough room in pending_buf.
  */
 static inline void put_uint64(deflate_state *s, uint64_t lld) {
-#if defined(UNALIGNED64_OK)
-    *(uint64_t *)(&s->pending_buf[s->pending]) = lld;
-    s->pending += 8;
-#elif defined(UNALIGNED_OK)
-    *(uint32_t *)(&s->pending_buf[s->pending]) = lld & 0xffffffff;
-    s->pending += 4;
-    *(uint32_t *)(&s->pending_buf[s->pending]) = (lld >> 32) & 0xffffffff;
-    s->pending += 4;
-#else
-    put_byte(s, (lld & 0xff));
-    put_byte(s, ((lld >> 8) & 0xff));
-    put_byte(s, ((lld >> 16) & 0xff));
-    put_byte(s, ((lld >> 24) & 0xff));
-    put_byte(s, ((lld >> 32) & 0xff));
-    put_byte(s, ((lld >> 40) & 0xff));
-    put_byte(s, ((lld >> 48) & 0xff));
-    put_byte(s, ((lld >> 56) & 0xff));
+#if BYTE_ORDER == BIG_ENDIAN
+    lld = ZSWAP64(lld);
 #endif
+    memcpy(&s->pending_buf[s->pending], &lld, sizeof(lld));
+    s->pending += 8;
 }
 
 #define MIN_LOOKAHEAD (STD_MAX_MATCH + STD_MIN_MATCH + 1)
index ad88275bfc5a544eabbd416cc8dc8bdb4d154bc2..7d3e46c897e21bc0bd772715ef65f769b8175a07 100644 (file)
@@ -31,7 +31,7 @@
 #ifndef HASH_CALC_READ
 #  ifdef UNALIGNED_OK
 #    define HASH_CALC_READ \
-        val = *(uint32_t *)(strstart);
+        memcpy(&val, strstart, sizeof(val));
 #  else
 #    define HASH_CALC_READ \
         val  = ((uint32_t)(strstart[0])); \
index e4e31e9819c1cc06b03092b6db61c13e0beae4f0..e11abfbb72b2a79085fa9068b1a5c6e449ac55f3 100644 (file)
@@ -85,11 +85,11 @@ Z_INTERNAL uint32_t LONGEST_MATCH(deflate_state *const s, Pos cur_match) {
     }
 #endif
 
-    scan_end   = *(bestcmp_t *)(scan+offset);
+    memcpy(&scan_end, scan+offset, sizeof(bestcmp_t));
 #ifndef UNALIGNED_OK
-    scan_end0  = *(bestcmp_t *)(scan+offset+1);
+    memcpy(&scan_end0, scan+offset+1, sizeof(bestcmp_t));
 #else
-    scan_start = *(bestcmp_t *)(scan);
+    memcpy(&scan_start, scan, sizeof(bestcmp_t));
 #endif
     mbase_end  = (mbase_start+offset);
 
@@ -207,9 +207,9 @@ Z_INTERNAL uint32_t LONGEST_MATCH(deflate_state *const s, Pos cur_match) {
 #endif
             }
 #endif
-            scan_end = *(bestcmp_t *)(scan+offset);
+            memcpy(&scan_end, scan+offset, sizeof(bestcmp_t));
 #ifndef UNALIGNED_OK
-            scan_end0 = *(bestcmp_t *)(scan+offset+1);
+            memcpy(&scan_end0, scan+offset+1, sizeof(bestcmp_t));
 #endif
 #ifdef LONGEST_MATCH_SLOW
             /* Look for a better string offset */