uint64_t prealign, aligned, remaining;
if (len < VX_MIN_LEN + VX_ALIGN_MASK)
- return crc32_big(crc, buf, len);
+ return crc32_byfour(crc, buf, len);
if ((uintptr_t)buf & VX_ALIGN_MASK) {
prealign = VX_ALIGNMENT - ((uintptr_t)buf & VX_ALIGN_MASK);
len -= prealign;
- crc = crc32_big(crc, buf, prealign);
+ crc = crc32_byfour(crc, buf, prealign);
buf += prealign;
}
aligned = len & ~VX_ALIGN_MASK;
crc = crc32_le_vgfm_16(crc ^ 0xffffffff, buf, (size_t)aligned) ^ 0xffffffff;
if (remaining)
- crc = crc32_big(crc, buf + aligned, remaining);
+ crc = crc32_byfour(crc, buf + aligned, remaining);
return crc;
}
#include "functable.h"
#include "crc32_tbl.h"
-/* =========================================================================
- * This function can be used by asm versions of crc32()
- */
+/* ========================================================================= */
const uint32_t * Z_EXPORT PREFIX(get_crc_table)(void) {
return (const uint32_t *)crc_table;
}
return functable.crc32(crc, buf, len);
}
-#endif
-/* ========================================================================= */
-#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
-#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
-#define DO4 DO1; DO1; DO1; DO1
-
-/* ========================================================================= */
-Z_INTERNAL uint32_t crc32_generic(uint32_t crc, const unsigned char *buf, uint64_t len) {
- crc = crc ^ 0xffffffff;
-
-#ifdef UNROLL_MORE
- while (len >= 8) {
- DO8;
- len -= 8;
- }
-#else
- while (len >= 4) {
- DO4;
- len -= 4;
- }
#endif
- if (len) do {
- DO1;
- } while (--len);
- return crc ^ 0xffffffff;
-}
-
#ifdef ZLIB_COMPAT
unsigned long Z_EXPORT PREFIX(crc32)(unsigned long crc, const unsigned char *buf, unsigned int len) {
return (unsigned long)PREFIX(crc32_z)((uint32_t)crc, buf, len);
}
#endif
+/* ========================================================================= */
+
/*
This BYFOUR code accesses the passed unsigned char * buffer with a 32-bit
integer pointer type. This violates the strict aliasing rule, where a
/* ========================================================================= */
#if BYTE_ORDER == LITTLE_ENDIAN
-#define DOLIT4 c ^= *buf4++; \
- c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
- crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
-#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
-
-/* ========================================================================= */
-Z_INTERNAL uint32_t crc32_little(uint32_t crc, const unsigned char *buf, uint64_t len) {
- Z_REGISTER uint32_t c;
- Z_REGISTER const uint32_t *buf4;
-
- c = crc;
- c = ~c;
- while (len && ((ptrdiff_t)buf & 3)) {
- c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
- len--;
- }
-
- buf4 = (const uint32_t *)(const void *)buf;
-
-#ifdef UNROLL_MORE
- while (len >= 32) {
- DOLIT32;
- len -= 32;
- }
+#define DOSWAP(crc) (crc)
+#define DO1 \
+ c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8)
+#define DO4 c ^= *buf4++; \
+ c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
+ crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
+#elif BYTE_ORDER == BIG_ENDIAN
+#define DOSWAP(crc) ZSWAP32(crc)
+#define DO1 \
+ c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8)
+#define DO4 c ^= *buf4++; \
+ c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
+ crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
+#else
+# error "No endian defined"
#endif
-
- while (len >= 4) {
- DOLIT4;
- len -= 4;
- }
- buf = (const unsigned char *)buf4;
-
- if (len) do {
- c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
- } while (--len);
- c = ~c;
- return c;
-}
-#endif /* BYTE_ORDER == LITTLE_ENDIAN */
-
-/* ========================================================================= */
-#if BYTE_ORDER == BIG_ENDIAN
-#define DOBIG4 c ^= *buf4++; \
- c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
- crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
-#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
+#define DO32 DO4; DO4; DO4; DO4; DO4; DO4; DO4; DO4
/* ========================================================================= */
-Z_INTERNAL uint32_t crc32_big(uint32_t crc, const unsigned char *buf, uint64_t len) {
+Z_INTERNAL uint32_t crc32_byfour(uint32_t crc, const unsigned char *buf, uint64_t len) {
Z_REGISTER uint32_t c;
Z_REGISTER const uint32_t *buf4;
- c = ZSWAP32(crc);
+ c = DOSWAP(crc);
c = ~c;
while (len && ((ptrdiff_t)buf & 3)) {
- c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
+ DO1;
len--;
}
#ifdef UNROLL_MORE
while (len >= 32) {
- DOBIG32;
+ DO32;
len -= 32;
}
#endif
while (len >= 4) {
- DOBIG4;
+ DO4;
len -= 4;
}
buf = (const unsigned char *)buf4;
if (len) do {
- c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
+ DO1;
} while (--len);
c = ~c;
- return ZSWAP32(c);
+ return DOSWAP(c);
}
-#endif /* BYTE_ORDER == BIG_ENDIAN */