@@ -700,24 +700,29 @@ local z_word_t crc_word_big(z_word_t data) {
700700/* ========================================================================= */
701701unsigned long ZEXPORT crc32_z (unsigned long crc , const unsigned char FAR * buf ,
702702 z_size_t len ) {
703+
704+ /* If no optimizations are enabled, do it as canonical zlib. */
705+ #if !defined(CRC32_SIMD_SSE42_PCLMUL ) && !defined(CRC32_ARMV8_CRC32 ) && \
706+ !defined(RISCV_RVV ) && !defined(CRC32_SIMD_AVX512_PCLMUL )
707+ if (buf == Z_NULL ) {
708+ return 0UL ;
709+ }
710+ #else
703711 /*
704712 * zlib convention is to call crc32(0, NULL, 0); before making
705713 * calls to crc32(). So this is a good, early (and infrequent)
706714 * place to cache CPU features if needed for those later, more
707715 * interesting crc32() calls.
708716 */
709- #if defined(CRC32_SIMD_SSE42_PCLMUL ) || defined(CRC32_ARMV8_CRC32 ) \
710- || defined(RISCV_RVV )
711- /*
712- * Since this routine can be freely used, check CPU features here.
713- */
714717 if (buf == Z_NULL ) {
715- if (!len ) /* Assume user is calling crc32(0, NULL, 0); */
718+ if (!len )
716719 cpu_check_features ();
717720 return 0UL ;
718721 }
719-
720722#endif
723+ /* If AVX-512 is enabled, we will use it for longer inputs and fallback
724+ * to SSE4.2 and eventually the portable implementation to handle the tail.
725+ */
721726#if defined(CRC32_SIMD_AVX512_PCLMUL )
722727 if (x86_cpu_enable_avx512 && len >= Z_CRC32_AVX512_MINIMUM_LENGTH ) {
723728 /* crc32 64-byte chunks */
@@ -730,7 +735,8 @@ unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf,
730735 /* Fall into the default crc32 for the remaining data. */
731736 buf += chunk_size ;
732737 }
733- #elif defined(CRC32_SIMD_SSE42_PCLMUL )
738+ #endif
739+ #if defined(CRC32_SIMD_SSE42_PCLMUL )
734740 if (x86_cpu_enable_simd && len >= Z_CRC32_SSE42_MINIMUM_LENGTH ) {
735741 /* crc32 16-byte chunks */
736742 z_size_t chunk_size = len & ~Z_CRC32_SSE42_CHUNKSIZE_MASK ;
@@ -758,11 +764,8 @@ unsigned long ZEXPORT crc32_z(unsigned long crc, const unsigned char FAR *buf,
758764 buf += chunk_size ;
759765 }
760766#endif
761- return armv8_crc32_little (buf , len , crc ); /* Armv8@32bit or tail. */
762- }
763- #else
764- if (buf == Z_NULL ) {
765- return 0UL ;
767+ /* This is scalar and self contained, used on Armv8@32bit or tail. */
768+ return armv8_crc32_little (buf , len , crc );
766769 }
767770#endif /* CRC32_SIMD */
768771
0 commit comments