#include "crc32_braid_p.h"
#include "crc32_braid_tbl.h"
-/* ========================================================================= */
-
/*
A CRC of a message is computed on N braids of words in the message, where
each word consists of W bytes (4 or 8). If N is 3, for example, then three
level. Your mileage may vary.
*/
-/* ========================================================================= */
-
-#if BYTE_ORDER == LITTLE_ENDIAN
-# define ZSWAPWORD(word) (word)
-# define BRAID_TABLE crc_braid_table
-#elif BYTE_ORDER == BIG_ENDIAN
-# if W == 8
-# define ZSWAPWORD(word) ZSWAP64(word)
-# elif W == 4
-# define ZSWAPWORD(word) ZSWAP32(word)
-# endif
-# define BRAID_TABLE crc_braid_big_table
-#else
-# error "No endian defined"
-#endif
-#define DO1 c = crc_table[(c ^ *buf++) & 0xff] ^ (c >> 8)
-#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
-
/* ========================================================================= */
#ifdef W
/*
/* ========================================================================= */
Z_INTERNAL uint32_t PREFIX(crc32_braid)(uint32_t crc, const uint8_t *buf, size_t len) {
- Z_REGISTER uint32_t c;
+ uint32_t c;
/* Pre-condition the CRC */
c = (~crc) & 0xffffffff;
#include "crc32.h"
#include "crc32_braid_p.h"
+#include "crc32_braid_tbl.h"
#include "x86_intrins.h"
#include <assert.h>
return crc->value;
}
+static inline uint32_t crc32_small(uint32_t crc, const uint8_t *buf, size_t len) {
+ uint32_t c = (~crc) & 0xffffffff;
+
+ while (len) {
+ len--;
+ DO1;
+ }
+
+ return c ^ 0xffffffff;
+}
+
Z_INTERNAL uint32_t CRC32(uint32_t crc32, const uint8_t *buf, size_t len) {
- /* For lens < 64, crc32_braid method is faster. The CRC32 instruction for
- * these short lengths might also prove to be effective */
- if (len < 64)
- return PREFIX(crc32_braid)(crc32, buf, len);
+ /* For lens smaller than ~12, crc32_small method is faster.
+ * But there are also minimum requirements for the pclmul functions due to alignment */
+ if (len < 32)
+ return crc32_small(crc32, buf, len);
crc32_fold ALIGNED_(16) crc_state;
CRC32_FOLD_RESET(&crc_state);
# endif
#endif
+#if BYTE_ORDER == LITTLE_ENDIAN
+# define ZSWAPWORD(word) (word)
+# define BRAID_TABLE crc_braid_table
+#elif BYTE_ORDER == BIG_ENDIAN
+# if W == 8
+# define ZSWAPWORD(word) ZSWAP64(word)
+# elif W == 4
+# define ZSWAPWORD(word) ZSWAP32(word)
+# endif
+# define BRAID_TABLE crc_braid_big_table
+#else
+# error "No endian defined"
+#endif
+
+#define DO1 c = crc_table[(c ^ *buf++) & 0xff] ^ (c >> 8)
+#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
+
/* CRC polynomial. */
#define POLY 0xedb88320 /* p(x) reflected, with x^32 implied */