xref: /freebsd-src/contrib/xz/src/liblzma/check/crc_common.h (revision 26743408e9ff53ac0e041407c359ed3c17c15596)
13b35e7eeSXin LI // SPDX-License-Identifier: 0BSD
23b35e7eeSXin LI 
33b35e7eeSXin LI ///////////////////////////////////////////////////////////////////////////////
43b35e7eeSXin LI //
53b35e7eeSXin LI /// \file       crc_common.h
63b35e7eeSXin LI /// \brief      Some functions and macros for CRC32 and CRC64
73b35e7eeSXin LI //
83b35e7eeSXin LI //  Authors:    Lasse Collin
93b35e7eeSXin LI //              Ilya Kurdyukov
103b35e7eeSXin LI //              Hans Jansen
113b35e7eeSXin LI //              Jia Tan
123b35e7eeSXin LI //
133b35e7eeSXin LI ///////////////////////////////////////////////////////////////////////////////
143b35e7eeSXin LI 
153b35e7eeSXin LI #ifndef LZMA_CRC_COMMON_H
163b35e7eeSXin LI #define LZMA_CRC_COMMON_H
173b35e7eeSXin LI 
183b35e7eeSXin LI #include "common.h"
193b35e7eeSXin LI 
203b35e7eeSXin LI 
213b35e7eeSXin LI #ifdef WORDS_BIGENDIAN
223b35e7eeSXin LI #	define A(x) ((x) >> 24)
233b35e7eeSXin LI #	define B(x) (((x) >> 16) & 0xFF)
243b35e7eeSXin LI #	define C(x) (((x) >> 8) & 0xFF)
253b35e7eeSXin LI #	define D(x) ((x) & 0xFF)
263b35e7eeSXin LI 
273b35e7eeSXin LI #	define S8(x) ((x) << 8)
283b35e7eeSXin LI #	define S32(x) ((x) << 32)
293b35e7eeSXin LI 
303b35e7eeSXin LI #else
313b35e7eeSXin LI #	define A(x) ((x) & 0xFF)
323b35e7eeSXin LI #	define B(x) (((x) >> 8) & 0xFF)
333b35e7eeSXin LI #	define C(x) (((x) >> 16) & 0xFF)
343b35e7eeSXin LI #	define D(x) ((x) >> 24)
353b35e7eeSXin LI 
363b35e7eeSXin LI #	define S8(x) ((x) >> 8)
373b35e7eeSXin LI #	define S32(x) ((x) >> 32)
383b35e7eeSXin LI #endif
393b35e7eeSXin LI 
403b35e7eeSXin LI 
413b35e7eeSXin LI // CRC CLMUL code needs this because accessing input buffers that aren't
423b35e7eeSXin LI // aligned to the vector size will inherently trip the address sanitizer.
433b35e7eeSXin LI #if lzma_has_attribute(__no_sanitize_address__)
443b35e7eeSXin LI #	define crc_attr_no_sanitize_address \
453b35e7eeSXin LI 			__attribute__((__no_sanitize_address__))
463b35e7eeSXin LI #else
473b35e7eeSXin LI #	define crc_attr_no_sanitize_address
483b35e7eeSXin LI #endif
493b35e7eeSXin LI 
503b35e7eeSXin LI // Keep this in sync with changes to crc32_arm64.h
513b35e7eeSXin LI #if defined(_WIN32) || defined(HAVE_GETAUXVAL) \
523b35e7eeSXin LI 		|| defined(HAVE_ELF_AUX_INFO) \
533b35e7eeSXin LI 		|| (defined(__APPLE__) && defined(HAVE_SYSCTLBYNAME))
543b35e7eeSXin LI #	define ARM64_RUNTIME_DETECTION 1
553b35e7eeSXin LI #endif
563b35e7eeSXin LI 
573b35e7eeSXin LI 
583b35e7eeSXin LI #undef CRC32_GENERIC
593b35e7eeSXin LI #undef CRC64_GENERIC
603b35e7eeSXin LI 
613b35e7eeSXin LI #undef CRC32_ARCH_OPTIMIZED
623b35e7eeSXin LI #undef CRC64_ARCH_OPTIMIZED
633b35e7eeSXin LI 
643b35e7eeSXin LI // The x86 CLMUL is used for both CRC32 and CRC64.
653b35e7eeSXin LI #undef CRC_X86_CLMUL
663b35e7eeSXin LI 
673b35e7eeSXin LI #undef CRC32_ARM64
683b35e7eeSXin LI #undef CRC64_ARM64_CLMUL
693b35e7eeSXin LI 
703b35e7eeSXin LI #undef CRC_USE_GENERIC_FOR_SMALL_INPUTS
713b35e7eeSXin LI 
723b35e7eeSXin LI // ARM64 CRC32 instruction is only useful for CRC32. Currently, only
733b35e7eeSXin LI // little endian is supported since we were unable to test on a big
743b35e7eeSXin LI // endian machine.
753b35e7eeSXin LI //
763b35e7eeSXin LI // NOTE: Keep this and the next check in sync with the macro
773b35e7eeSXin LI //       NO_CRC32_TABLE in crc32_table.c
783b35e7eeSXin LI #if defined(HAVE_ARM64_CRC32) && !defined(WORDS_BIGENDIAN)
793b35e7eeSXin LI 	// Allow ARM64 CRC32 instruction without a runtime check if
80*26743408SXin LI 	// __ARM_FEATURE_CRC32 is defined. GCC and Clang only define
81*26743408SXin LI 	// this if the proper compiler options are used.
823b35e7eeSXin LI #	if defined(__ARM_FEATURE_CRC32)
833b35e7eeSXin LI #		define CRC32_ARCH_OPTIMIZED 1
843b35e7eeSXin LI #		define CRC32_ARM64 1
853b35e7eeSXin LI #	elif defined(ARM64_RUNTIME_DETECTION)
863b35e7eeSXin LI #		define CRC32_ARCH_OPTIMIZED 1
873b35e7eeSXin LI #		define CRC32_ARM64 1
883b35e7eeSXin LI #		define CRC32_GENERIC 1
893b35e7eeSXin LI #	endif
903b35e7eeSXin LI #endif
913b35e7eeSXin LI 
923b35e7eeSXin LI #if defined(HAVE_USABLE_CLMUL)
933b35e7eeSXin LI // If CLMUL is allowed unconditionally in the compiler options then the
943b35e7eeSXin LI // generic version can be omitted. Note that this doesn't work with MSVC
953b35e7eeSXin LI // as I don't know how to detect the features here.
963b35e7eeSXin LI //
973b35e7eeSXin LI // NOTE: Keep this in sync with the NO_CRC32_TABLE macro in crc32_table.c
983b35e7eeSXin LI // and NO_CRC64_TABLE in crc64_table.c.
993b35e7eeSXin LI #	if (defined(__SSSE3__) && defined(__SSE4_1__) && defined(__PCLMUL__)) \
1003b35e7eeSXin LI 		|| (defined(__e2k__) && __iset__ >= 6)
1013b35e7eeSXin LI #		define CRC32_ARCH_OPTIMIZED 1
1023b35e7eeSXin LI #		define CRC64_ARCH_OPTIMIZED 1
1033b35e7eeSXin LI #		define CRC_X86_CLMUL 1
1043b35e7eeSXin LI #	else
1053b35e7eeSXin LI #		define CRC32_GENERIC 1
1063b35e7eeSXin LI #		define CRC64_GENERIC 1
1073b35e7eeSXin LI #		define CRC32_ARCH_OPTIMIZED 1
1083b35e7eeSXin LI #		define CRC64_ARCH_OPTIMIZED 1
1093b35e7eeSXin LI #		define CRC_X86_CLMUL 1
1103b35e7eeSXin LI 
1113b35e7eeSXin LI /*
1123b35e7eeSXin LI 		// The generic code is much faster with 1-8-byte inputs and
1133b35e7eeSXin LI 		// has similar performance up to 16 bytes  at least in
1143b35e7eeSXin LI 		// microbenchmarks (it depends on input buffer alignment
1153b35e7eeSXin LI 		// too). If both versions are built, this #define will use
1163b35e7eeSXin LI 		// the generic version for inputs up to 16 bytes and CLMUL
1173b35e7eeSXin LI 		// for bigger inputs. It saves a little in code size since
1183b35e7eeSXin LI 		// the special cases for 0-16-byte inputs will be omitted
1193b35e7eeSXin LI 		// from the CLMUL code.
1203b35e7eeSXin LI #		define CRC_USE_GENERIC_FOR_SMALL_INPUTS 1
1213b35e7eeSXin LI */
1223b35e7eeSXin LI #	endif
1233b35e7eeSXin LI #endif
1243b35e7eeSXin LI 
1253b35e7eeSXin LI // For CRC32 use the generic slice-by-eight implementation if no optimized
1263b35e7eeSXin LI // version is available.
1273b35e7eeSXin LI #if !defined(CRC32_ARCH_OPTIMIZED) && !defined(CRC32_GENERIC)
1283b35e7eeSXin LI #	define CRC32_GENERIC 1
1293b35e7eeSXin LI #endif
1303b35e7eeSXin LI 
1313b35e7eeSXin LI // For CRC64 use the generic slice-by-four implementation if no optimized
1323b35e7eeSXin LI // version is available.
1333b35e7eeSXin LI #if !defined(CRC64_ARCH_OPTIMIZED) && !defined(CRC64_GENERIC)
1343b35e7eeSXin LI #	define CRC64_GENERIC 1
1353b35e7eeSXin LI #endif
1363b35e7eeSXin LI 
1373b35e7eeSXin LI #endif
138