< prev index next >

src/java.base/share/native/libzip/zlib/zcrc32.c

Print this page
*** 125,33 ***
  /* If available, use the ARM processor CRC32 instruction. */
  #if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) && W == 8
  #  define ARMCRC32
  #endif
  
- /* 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));
- 
- #if defined(W) && (!defined(ARMCRC32) || defined(DYNAMIC_CRC_TABLE))
-     local z_word_t byte_swap OF((z_word_t word));
- #endif
- 
- #if defined(W) && !defined(ARMCRC32)
-     local z_crc_t crc_word OF((z_word_t data));
-     local z_word_t crc_word_big OF((z_word_t data));
- #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 |
--- 125,18 ---
  /* 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(z_word_t word) {
  #  if W == 8
      return
          (word & 0xff00000000000000) >> 56 |
          (word & 0xff000000000000) >> 40 |
          (word & 0xff0000000000) >> 24 |

*** 168,28 ***
          (word & 0xff) << 24;
  #  endif
  }
  #endif
  
  /* CRC polynomial. */
  #define POLY 0xedb88320         /* p(x) reflected, with x^32 implied */
  
! #ifdef DYNAMIC_CRC_TABLE
  
  local z_crc_t FAR crc_table[256];
- local z_crc_t FAR x2n_table[32];
- local void make_crc_table OF((void));
  #ifdef W
     local z_word_t FAR crc_big_table[256];
     local z_crc_t FAR crc_braid_table[W][256];
     local z_word_t FAR crc_braid_big_table[W][256];
!    local void braid OF((z_crc_t [][256], z_word_t [][256], int, int));
  #endif
  #ifdef MAKECRCH
!    local void write_table OF((FILE *, const z_crc_t FAR *, int));
!    local void write_table32hi OF((FILE *, const z_word_t FAR *, int));
!    local void write_table64 OF((FILE *, const z_word_t FAR *, int));
  #endif /* MAKECRCH */
  
  /*
    Define a once() function depending on the availability of atomics. If this is
    compiled with DYNAMIC_CRC_TABLE defined, and if CRCs will be computed in
--- 153,81 ---
          (word & 0xff) << 24;
  #  endif
  }
  #endif
  
+ #ifdef DYNAMIC_CRC_TABLE
+ /* =========================================================================
+  * Table of powers of x for combining CRC-32s, filled in by make_crc_table()
+  * below.
+  */
+    local z_crc_t FAR x2n_table[32];
+ #else
+ /* =========================================================================
+  * Tables for byte-wise and braided CRC-32 calculations, and a table of powers
+  * of x for combining CRC-32s, all made by make_crc_table().
+  */
+ #  include "crc32.h"
+ #endif
+ 
  /* CRC polynomial. */
  #define POLY 0xedb88320         /* p(x) reflected, with x^32 implied */
  
! /*
+   Return a(x) multiplied by b(x) modulo p(x), where p(x) is the CRC polynomial,
+   reflected. For speed, this requires that a not be zero.
+  */
+ local z_crc_t multmodp(z_crc_t a, z_crc_t b) {
+     z_crc_t m, p;
+ 
+     m = (z_crc_t)1 << 31;
+     p = 0;
+     for (;;) {
+         if (a & m) {
+             p ^= b;
+             if ((a & (m - 1)) == 0)
+                 break;
+         }
+         m >>= 1;
+         b = b & 1 ? (b >> 1) ^ POLY : b >> 1;
+     }
+     return p;
+ }
  
+ /*
+   Return x^(n * 2^k) modulo p(x). Requires that x2n_table[] has been
+   initialized.
+  */
+ local z_crc_t x2nmodp(z_off64_t n, unsigned k) {
+     z_crc_t p;
+ 
+     p = (z_crc_t)1 << 31;           /* x^0 == 1 */
+     while (n) {
+         if (n & 1)
+             p = multmodp(x2n_table[k & 31], p);
+         n >>= 1;
+         k++;
+     }
+     return p;
+ }
+ 
+ #ifdef DYNAMIC_CRC_TABLE
+ /* =========================================================================
+  * Build the tables for byte-wise and braided CRC-32 calculations, and a table
+  * of powers of x for combining CRC-32s.
+  */
  local z_crc_t FAR crc_table[256];
  #ifdef W
     local z_word_t FAR crc_big_table[256];
     local z_crc_t FAR crc_braid_table[W][256];
     local z_word_t FAR crc_braid_big_table[W][256];
!    local void braid(z_crc_t [][256], z_word_t [][256], int, int);
  #endif
  #ifdef MAKECRCH
!    local void write_table(FILE *, const z_crc_t FAR *, int);
!    local void write_table32hi(FILE *, const z_word_t FAR *, int);
!    local void write_table64(FILE *, const z_word_t FAR *, int);
  #endif /* MAKECRCH */
  
  /*
    Define a once() function depending on the availability of atomics. If this is
    compiled with DYNAMIC_CRC_TABLE defined, and if CRCs will be computed in

*** 198,11 ***
    allowed to compute or combine CRCs.
   */
  
  /* Definition of once functionality. */
  typedef struct once_s once_t;
- local void once OF((once_t *, void (*)(void)));
  
  /* Check for the availability of atomics. */
  #if defined(__STDC__) && __STDC_VERSION__ >= 201112L && \
      !defined(__STDC_NO_ATOMICS__)
  
--- 236,10 ---

*** 218,14 ***
  /*
    Run the provided init() function exactly once, even if multiple threads
    invoke once() at the same time. The state must be a once_t initialized with
    ONCE_INIT.
   */
! local void once(state, init)
-     once_t *state;
-     void (*init)(void);
- {
      if (!atomic_load(&state->done)) {
          if (atomic_flag_test_and_set(&state->begun))
              while (!atomic_load(&state->done))
                  ;
          else {
--- 255,11 ---
  /*
    Run the provided init() function exactly once, even if multiple threads
    invoke once() at the same time. The state must be a once_t initialized with
    ONCE_INIT.
   */
! local void once(once_t *state, void (*init)(void)) {
      if (!atomic_load(&state->done)) {
          if (atomic_flag_test_and_set(&state->begun))
              while (!atomic_load(&state->done))
                  ;
          else {

*** 244,26 ***
  };
  #define ONCE_INIT {0, 0}
  
  /* Test and set. Alas, not atomic, but tries to minimize the period of
     vulnerability. */
! local int test_and_set OF((int volatile *));
- local int test_and_set(flag)
-     int volatile *flag;
- {
      int was;
  
      was = *flag;
      *flag = 1;
      return was;
  }
  
  /* Run the provided init() function once. This is not thread-safe. */
! local void once(state, init)
-     once_t *state;
-     void (*init)(void);
- {
      if (!state->done) {
          if (test_and_set(&state->begun))
              while (!state->done)
                  ;
          else {
--- 278,20 ---
  };
  #define ONCE_INIT {0, 0}
  
  /* Test and set. Alas, not atomic, but tries to minimize the period of
     vulnerability. */
! local int test_and_set(int volatile *flag) {
      int was;
  
      was = *flag;
      *flag = 1;
      return was;
  }
  
  /* Run the provided init() function once. This is not thread-safe. */
! local void once(once_t *state, void (*init)(void)) {
      if (!state->done) {
          if (test_and_set(&state->begun))
              while (!state->done)
                  ;
          else {

*** 301,12 ***
    The table is simply the CRC of all possible eight bit values. This is all the
    information needed to generate CRCs on data a byte at a time for all
    combinations of CRC register values and incoming bytes.
   */
  
! local void make_crc_table()
- {
      unsigned i, j, n;
      z_crc_t p;
  
      /* initialize the CRC of bytes tables */
      for (i = 0; i < 256; i++) {
--- 329,11 ---
    The table is simply the CRC of all possible eight bit values. This is all the
    information needed to generate CRCs on data a byte at a time for all
    combinations of CRC register values and incoming bytes.
   */
  
! local void make_crc_table(void) {
      unsigned i, j, n;
      z_crc_t p;
  
      /* initialize the CRC of bytes tables */
      for (i = 0; i < 256; i++) {

*** 469,15 ***
  
  /*
     Write the 32-bit values in table[0..k-1] to out, five per line in
     hexadecimal separated by commas.
   */
! local void write_table(out, table, k)
-     FILE *out;
-     const z_crc_t FAR *table;
-     int k;
- {
      int n;
  
      for (n = 0; n < k; n++)
          fprintf(out, "%s0x%08lx%s", n == 0 || n % 5 ? "" : "    ",
                  (unsigned long)(table[n]),
--- 496,11 ---
  
  /*
     Write the 32-bit values in table[0..k-1] to out, five per line in
     hexadecimal separated by commas.
   */
! local void write_table(FILE *out, const z_crc_t FAR *table, int k) {
      int n;
  
      for (n = 0; n < k; n++)
          fprintf(out, "%s0x%08lx%s", n == 0 || n % 5 ? "" : "    ",
                  (unsigned long)(table[n]),

*** 486,15 ***
  
  /*
     Write the high 32-bits of each value in table[0..k-1] to out, five per line
     in hexadecimal separated by commas.
   */
! local void write_table32hi(out, table, k)
- FILE *out;
- const z_word_t FAR *table;
- int k;
- {
      int n;
  
      for (n = 0; n < k; n++)
          fprintf(out, "%s0x%08lx%s", n == 0 || n % 5 ? "" : "    ",
                  (unsigned long)(table[n] >> 32),
--- 509,11 ---
  
  /*
     Write the high 32-bits of each value in table[0..k-1] to out, five per line
     in hexadecimal separated by commas.
   */
! local void write_table32hi(FILE *out, const z_word_t FAR *table, int k) {
      int n;
  
      for (n = 0; n < k; n++)
          fprintf(out, "%s0x%08lx%s", n == 0 || n % 5 ? "" : "    ",
                  (unsigned long)(table[n] >> 32),

*** 506,26 ***
    hexadecimal separated by commas. This assumes that if there is a 64-bit
    type, then there is also a long long integer type, and it is at least 64
    bits. If not, then the type cast and format string can be adjusted
    accordingly.
   */
! local void write_table64(out, table, k)
-     FILE *out;
-     const z_word_t FAR *table;
-     int k;
- {
      int n;
  
      for (n = 0; n < k; n++)
          fprintf(out, "%s0x%016llx%s", n == 0 || n % 3 ? "" : "    ",
                  (unsigned long long)(table[n]),
                  n == k - 1 ? "" : (n % 3 == 2 ? ",\n" : ", "));
  }
  
  /* Actually do the deed. */
! int main()
- {
      make_crc_table();
      return 0;
  }
  
  #endif /* MAKECRCH */
--- 525,21 ---
    hexadecimal separated by commas. This assumes that if there is a 64-bit
    type, then there is also a long long integer type, and it is at least 64
    bits. If not, then the type cast and format string can be adjusted
    accordingly.
   */
! local void write_table64(FILE *out, const z_word_t FAR *table, int k) {
      int n;
  
      for (n = 0; n < k; n++)
          fprintf(out, "%s0x%016llx%s", n == 0 || n % 3 ? "" : "    ",
                  (unsigned long long)(table[n]),
                  n == k - 1 ? "" : (n % 3 == 2 ? ",\n" : ", "));
  }
  
  /* Actually do the deed. */
! int main(void) {
      make_crc_table();
      return 0;
  }
  
  #endif /* MAKECRCH */

*** 533,16 ***
  #ifdef W
  /*
    Generate the little and big-endian braid tables for the given n and z_word_t
    size w. Each array must have room for w blocks of 256 elements.
   */
! local void braid(ltl, big, n, w)
-     z_crc_t ltl[][256];
-     z_word_t big[][256];
-     int n;
-     int w;
- {
      int k;
      z_crc_t i, p, q;
      for (k = 0; k < w; k++) {
          p = x2nmodp((n * w + 3 - k) << 3, 0);
          ltl[k][0] = 0;
--- 547,11 ---
  #ifdef W
  /*
    Generate the little and big-endian braid tables for the given n and z_word_t
    size w. Each array must have room for w blocks of 256 elements.
   */
! local void braid(z_crc_t ltl[][256], z_word_t big[][256], int n, int w) {
      int k;
      z_crc_t i, p, q;
      for (k = 0; k < w; k++) {
          p = x2nmodp((n * w + 3 - k) << 3, 0);
          ltl[k][0] = 0;

*** 553,73 ***
          }
      }
  }
  #endif
  
- #else /* !DYNAMIC_CRC_TABLE */
- /* ========================================================================
-  * Tables for byte-wise and braided CRC-32 calculations, and a table of powers
-  * of x for combining CRC-32s, all made by make_crc_table().
-  */
- #include "crc32.h"
  #endif /* DYNAMIC_CRC_TABLE */
  
- /* ========================================================================
-  * Routines used for CRC calculation. Some are also required for the table
-  * generation above.
-  */
- 
- /*
-   Return a(x) multiplied by b(x) modulo p(x), where p(x) is the CRC polynomial,
-   reflected. For speed, this requires that a not be zero.
-  */
- local z_crc_t multmodp(a, b)
-     z_crc_t a;
-     z_crc_t b;
- {
-     z_crc_t m, p;
- 
-     m = (z_crc_t)1 << 31;
-     p = 0;
-     for (;;) {
-         if (a & m) {
-             p ^= b;
-             if ((a & (m - 1)) == 0)
-                 break;
-         }
-         m >>= 1;
-         b = b & 1 ? (b >> 1) ^ POLY : b >> 1;
-     }
-     return p;
- }
- 
- /*
-   Return x^(n * 2^k) modulo p(x). Requires that x2n_table[] has been
-   initialized.
-  */
- local z_crc_t x2nmodp(n, k)
-     z_off64_t n;
-     unsigned k;
- {
-     z_crc_t p;
- 
-     p = (z_crc_t)1 << 31;           /* x^0 == 1 */
-     while (n) {
-         if (n & 1)
-             p = multmodp(x2n_table[k & 31], p);
-         n >>= 1;
-         k++;
-     }
-     return p;
- }
- 
  /* =========================================================================
   * This function can be used by asm versions of crc32(), and to force the
   * generation of the CRC tables in a threaded application.
   */
! const z_crc_t FAR * ZEXPORT get_crc_table()
- {
  #ifdef DYNAMIC_CRC_TABLE
      once(&made, make_crc_table);
  #endif /* DYNAMIC_CRC_TABLE */
      return (const z_crc_t FAR *)crc_table;
  }
--- 562,17 ---
          }
      }
  }
  #endif
  
  #endif /* DYNAMIC_CRC_TABLE */
  
  /* =========================================================================
   * This function can be used by asm versions of crc32(), and to force the
   * generation of the CRC tables in a threaded application.
   */
! const z_crc_t FAR * ZEXPORT get_crc_table(void) {
  #ifdef DYNAMIC_CRC_TABLE
      once(&made, make_crc_table);
  #endif /* DYNAMIC_CRC_TABLE */
      return (const z_crc_t FAR *)crc_table;
  }

*** 641,15 ***
   */
  #define Z_BATCH 3990                /* number of words in a batch */
  #define Z_BATCH_ZEROS 0xa10d3d0c    /* computed from Z_BATCH = 3990 */
  #define Z_BATCH_MIN 800             /* fewest words in a final batch */
  
! unsigned long ZEXPORT crc32_z(crc, buf, len)
!     unsigned long crc;
-     const unsigned char FAR *buf;
-     z_size_t len;
- {
      z_crc_t val;
      z_word_t crc1, crc2;
      const z_word_t *word;
      z_word_t val0, val1, val2;
      z_size_t last, last2, i;
--- 594,12 ---
   */
  #define Z_BATCH 3990                /* number of words in a batch */
  #define Z_BATCH_ZEROS 0xa10d3d0c    /* computed from Z_BATCH = 3990 */
  #define Z_BATCH_MIN 800             /* fewest words in a final batch */
  
! unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf,
!                               z_size_t len) {
      z_crc_t val;
      z_word_t crc1, crc2;
      const z_word_t *word;
      z_word_t val0, val1, val2;
      z_size_t last, last2, i;

*** 745,37 ***
  /*
    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;
-     const unsigned char FAR *buf;
-     z_size_t len;
- {
      /* Return initial CRC, if requested. */
      if (buf == Z_NULL) return 0;
  
  #ifdef DYNAMIC_CRC_TABLE
      once(&made, make_crc_table);
--- 695,30 ---
  /*
    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(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(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(unsigned long crc, const unsigned char FAR *buf,
!                               z_size_t len) {
      /* Return initial CRC, if requested. */
      if (buf == Z_NULL) return 0;
  
  #ifdef DYNAMIC_CRC_TABLE
      once(&made, make_crc_table);

*** 803,12 ***
          blks = len / (N * W);
          len -= blks * N * W;
          words = (z_word_t const *)buf;
  
          /* Do endian check at execution time instead of compile time, since ARM
!            processors can change the endianess at execution time. If the
!            compiler knows what the endianess will be, it can optimize out the
             check and the unused branch. */
          endian = 1;
          if (*(unsigned char *)&endian) {
              /* Little endian. */
  
--- 746,12 ---
          blks = len / (N * W);
          len -= blks * N * W;
          words = (z_word_t const *)buf;
  
          /* Do endian check at execution time instead of compile time, since ARM
!            processors can change the endianness at execution time. If the
!            compiler knows what the endianness will be, it can optimize out the
             check and the unused branch. */
          endian = 1;
          if (*(unsigned char *)&endian) {
              /* Little endian. */
  

*** 1091,59 ***
  }
  
  #endif
  
  /* ========================================================================= */
! unsigned long ZEXPORT crc32(crc, buf, len)
!     unsigned long crc;
-     const unsigned char FAR *buf;
-     uInt len;
- {
      return crc32_z(crc, buf, len);
  }
  
  /* ========================================================================= */
! uLong ZEXPORT crc32_combine64(crc1, crc2, len2)
-     uLong crc1;
-     uLong crc2;
-     z_off64_t len2;
- {
  #ifdef DYNAMIC_CRC_TABLE
      once(&made, make_crc_table);
  #endif /* DYNAMIC_CRC_TABLE */
      return multmodp(x2nmodp(len2, 3), crc1) ^ (crc2 & 0xffffffff);
  }
  
  /* ========================================================================= */
! uLong ZEXPORT crc32_combine(crc1, crc2, len2)
-     uLong crc1;
-     uLong crc2;
-     z_off_t len2;
- {
      return crc32_combine64(crc1, crc2, (z_off64_t)len2);
  }
  
  /* ========================================================================= */
! uLong ZEXPORT crc32_combine_gen64(len2)
-     z_off64_t len2;
- {
  #ifdef DYNAMIC_CRC_TABLE
      once(&made, make_crc_table);
  #endif /* DYNAMIC_CRC_TABLE */
      return x2nmodp(len2, 3);
  }
  
  /* ========================================================================= */
! uLong ZEXPORT crc32_combine_gen(len2)
-     z_off_t len2;
- {
      return crc32_combine_gen64((z_off64_t)len2);
  }
  
  /* ========================================================================= */
! uLong ZEXPORT crc32_combine_op(crc1, crc2, op)
-     uLong crc1;
-     uLong crc2;
-     uLong op;
- {
      return multmodp(op, crc1) ^ (crc2 & 0xffffffff);
  }
--- 1034,40 ---
  }
  
  #endif
  
  /* ========================================================================= */
! unsigned long ZEXPORT crc32(unsigned long crc, const unsigned char FAR *buf,
!                             uInt len) {
      return crc32_z(crc, buf, len);
  }
  
  /* ========================================================================= */
! uLong ZEXPORT crc32_combine64(uLong crc1, uLong crc2, z_off64_t len2) {
  #ifdef DYNAMIC_CRC_TABLE
      once(&made, make_crc_table);
  #endif /* DYNAMIC_CRC_TABLE */
      return multmodp(x2nmodp(len2, 3), crc1) ^ (crc2 & 0xffffffff);
  }
  
  /* ========================================================================= */
! uLong ZEXPORT crc32_combine(uLong crc1, uLong crc2, z_off_t len2) {
      return crc32_combine64(crc1, crc2, (z_off64_t)len2);
  }
  
  /* ========================================================================= */
! uLong ZEXPORT crc32_combine_gen64(z_off64_t len2) {
  #ifdef DYNAMIC_CRC_TABLE
      once(&made, make_crc_table);
  #endif /* DYNAMIC_CRC_TABLE */
      return x2nmodp(len2, 3);
  }
  
  /* ========================================================================= */
! uLong ZEXPORT crc32_combine_gen(z_off_t len2) {
      return crc32_combine_gen64((z_off64_t)len2);
  }
  
  /* ========================================================================= */
! uLong ZEXPORT crc32_combine_op(uLong crc1, uLong crc2, uLong op) {
      return multmodp(op, crc1) ^ (crc2 & 0xffffffff);
  }
< prev index next >