]> git.lizzy.rs Git - zlib.git/blobdiff - crc32.c
CMake build fixes
[zlib.git] / crc32.c
diff --git a/crc32.c b/crc32.c
index 2d2082904048b1a19eaeb2bfd203245e94cfc23b..a1bdce5c23c6b8fa26e22cbedf9b761fddb6c1e8 100644 (file)
--- a/crc32.c
+++ b/crc32.c
@@ -1,5 +1,5 @@
 /* crc32.c -- compute the CRC-32 of a data stream
- * Copyright (C) 1995-2006, 2010, 2011, 2012, 2016, 2018 Mark Adler
+ * Copyright (C) 1995-2022 Mark Adler
  * For conditions of distribution and use, see copyright notice in zlib.h
  *
  * This interleaved implementation of a CRC makes use of pipelined multiple
 /* Local functions. */
 local z_crc_t multmodp OF((z_crc_t a, z_crc_t b));
 local z_crc_t x2nmodp OF((z_off64_t n, unsigned k));
-#ifdef W
-   local z_word_t byte_swap OF((z_word_t word));
-   local z_crc_t crc_word OF((z_word_t data));
-   local z_word_t crc_word_big OF((z_word_t data));
-#endif /* W */
+
+/* If available, use the ARM processor CRC32 instruction. */
+#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) && W == 8
+#  define ARMCRC32
+#endif
+
+#if defined(W) && (!defined(ARMCRC32) || defined(DYNAMIC_CRC_TABLE))
+/*
+  Swap the bytes in a z_word_t to convert between little and big endian. Any
+  self-respecting compiler will optimize this to a single machine byte-swap
+  instruction, if one is available. This assumes that word_t is either 32 bits
+  or 64 bits.
+ */
+local z_word_t byte_swap(word)
+    z_word_t word;
+{
+#  if W == 8
+    return
+        (word & 0xff00000000000000) >> 56 |
+        (word & 0xff000000000000) >> 40 |
+        (word & 0xff0000000000) >> 24 |
+        (word & 0xff00000000) >> 8 |
+        (word & 0xff000000) << 8 |
+        (word & 0xff0000) << 24 |
+        (word & 0xff00) << 40 |
+        (word & 0xff) << 56;
+#  else   /* W == 4 */
+    return
+        (word & 0xff000000) >> 24 |
+        (word & 0xff0000) >> 8 |
+        (word & 0xff00) << 8 |
+        (word & 0xff) << 24;
+#  endif
+}
+#endif
 
 /* CRC polynomial. */
 #define POLY 0xedb88320         /* p(x) reflected, with x^32 implied */
@@ -224,7 +254,7 @@ local once_t made = ONCE_INIT;
   is just exclusive-or, and multiplying a polynomial by x is a right shift by
   one. If we call the above polynomial p, and represent a byte as the
   polynomial q, also with the lowest power in the most significant bit (so the
-  byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
+  byte 0xb1 is the polynomial x^7+x^3+x^2+1), then the CRC is (q*x^32) mod p,
   where a mod b means the remainder after dividing a by b.
 
   This calculation is done using the shift-register method of multiplying and
@@ -549,62 +579,6 @@ local z_crc_t x2nmodp(n, k)
     return p;
 }
 
-#ifdef W
-
-/*
-  Swap the bytes in a z_word_t to convert between little and big endian. Any
-  self-respecting compiler will optimize this to a single machine byte-swap
-  instruction, if one is available. This assumes that word_t is either 32 bits
-  or 64 bits.
- */
-local z_word_t byte_swap(word)
-    z_word_t word;
-{
-#if W == 8
-    return
-        (word & 0xff00000000000000) >> 56 |
-        (word & 0xff000000000000) >> 40 |
-        (word & 0xff0000000000) >> 24 |
-        (word & 0xff00000000) >> 8 |
-        (word & 0xff000000) << 8 |
-        (word & 0xff0000) << 24 |
-        (word & 0xff00) << 40 |
-        (word & 0xff) << 56;
-#else   /* W == 4 */
-    return
-        (word & 0xff000000) >> 24 |
-        (word & 0xff0000) >> 8 |
-        (word & 0xff00) << 8 |
-        (word & 0xff) << 24;
-#endif
-}
-
-/*
-  Return the CRC of the W bytes in the word_t data, taking the
-  least-significant byte of the word as the first byte of data, without any pre
-  or post conditioning. This is used to combine the CRCs of each braid.
- */
-local z_crc_t crc_word(data)
-    z_word_t data;
-{
-    int k;
-    for (k = 0; k < W; k++)
-        data = (data >> 8) ^ crc_table[data & 0xff];
-    return (z_crc_t)data;
-}
-
-local z_word_t crc_word_big(data)
-    z_word_t data;
-{
-    int k;
-    for (k = 0; k < W; k++)
-        data = (data << 8) ^
-            crc_big_table[(data >> ((W - 1) << 3)) & 0xff];
-    return data;
-}
-
-#endif /* W */
-
 /* =========================================================================
  * This function can be used by asm versions of crc32(), and to force the
  * generation of the CRC tables in a threaded application.
@@ -618,11 +592,15 @@ const z_crc_t FAR * ZEXPORT get_crc_table()
 }
 
 /* =========================================================================
- * Use ARM machine instructions if requested. This will compute the CRC about
+ * Use ARM machine instructions if available. This will compute the CRC about
  * ten times faster than the braided calculation. This code does not check for
- * the presence of the CRC instruction. Compile with care.
+ * the presence of the CRC instruction at run time. __ARM_FEATURE_CRC32 will
+ * only be defined if the compilation specifies an ARM processor architecture
+ * that has the instructions. For example, compiling with -march=armv8.1-a or
+ * -march=armv8-a+crc, or -march=native if the compile machine has the crc32
+ * instructions.
  */
-#if defined(Z_ARM_CRC32) && defined(__aarch64__) && W == 8
+#ifdef ARMCRC32
 
 /*
    Constants empirically determined to maximize speed. These values are from
@@ -729,6 +707,34 @@ unsigned long ZEXPORT crc32_z(crc, buf, len)
 
 #else
 
+#ifdef W
+
+/*
+  Return the CRC of the W bytes in the word_t data, taking the
+  least-significant byte of the word as the first byte of data, without any pre
+  or post conditioning. This is used to combine the CRCs of each braid.
+ */
+local z_crc_t crc_word(data)
+    z_word_t data;
+{
+    int k;
+    for (k = 0; k < W; k++)
+        data = (data >> 8) ^ crc_table[data & 0xff];
+    return (z_crc_t)data;
+}
+
+local z_word_t crc_word_big(data)
+    z_word_t data;
+{
+    int k;
+    for (k = 0; k < W; k++)
+        data = (data << 8) ^
+            crc_big_table[(data >> ((W - 1) << 3)) & 0xff];
+    return data;
+}
+
+#endif
+
 /* ========================================================================= */
 unsigned long ZEXPORT crc32_z(crc, buf, len)
     unsigned long crc;