crc_common.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. // SPDX-License-Identifier: 0BSD
  2. ///////////////////////////////////////////////////////////////////////////////
  3. //
  4. /// \file crc_common.h
  5. /// \brief Some functions and macros for CRC32 and CRC64
  6. //
  7. // Authors: Lasse Collin
  8. // Ilya Kurdyukov
  9. // Hans Jansen
  10. // Jia Tan
  11. //
  12. ///////////////////////////////////////////////////////////////////////////////
  13. #ifndef LZMA_CRC_COMMON_H
  14. #define LZMA_CRC_COMMON_H
  15. #include "common.h"
  16. #ifdef WORDS_BIGENDIAN
  17. # define A(x) ((x) >> 24)
  18. # define B(x) (((x) >> 16) & 0xFF)
  19. # define C(x) (((x) >> 8) & 0xFF)
  20. # define D(x) ((x) & 0xFF)
  21. # define S8(x) ((x) << 8)
  22. # define S32(x) ((x) << 32)
  23. #else
  24. # define A(x) ((x) & 0xFF)
  25. # define B(x) (((x) >> 8) & 0xFF)
  26. # define C(x) (((x) >> 16) & 0xFF)
  27. # define D(x) ((x) >> 24)
  28. # define S8(x) ((x) >> 8)
  29. # define S32(x) ((x) >> 32)
  30. #endif
  31. // CRC CLMUL code needs this because accessing input buffers that aren't
  32. // aligned to the vector size will inherently trip the address sanitizer.
  33. #if lzma_has_attribute(__no_sanitize_address__)
  34. # define crc_attr_no_sanitize_address \
  35. __attribute__((__no_sanitize_address__))
  36. #else
  37. # define crc_attr_no_sanitize_address
  38. #endif
  39. // Keep this in sync with changes to crc32_arm64.h
  40. #if defined(_WIN32) || defined(HAVE_GETAUXVAL) \
  41. || defined(HAVE_ELF_AUX_INFO) \
  42. || (defined(__APPLE__) && defined(HAVE_SYSCTLBYNAME))
  43. # define ARM64_RUNTIME_DETECTION 1
  44. #endif
  45. #undef CRC32_GENERIC
  46. #undef CRC64_GENERIC
  47. #undef CRC32_ARCH_OPTIMIZED
  48. #undef CRC64_ARCH_OPTIMIZED
  49. // The x86 CLMUL is used for both CRC32 and CRC64.
  50. #undef CRC_X86_CLMUL
  51. #undef CRC32_ARM64
  52. #undef CRC64_ARM64_CLMUL
  53. #undef CRC_USE_GENERIC_FOR_SMALL_INPUTS
  54. // ARM64 CRC32 instruction is only useful for CRC32. Currently, only
  55. // little endian is supported since we were unable to test on a big
  56. // endian machine.
  57. //
  58. // NOTE: Keep this and the next check in sync with the macro
  59. // NO_CRC32_TABLE in crc32_table.c
  60. #if defined(HAVE_ARM64_CRC32) && !defined(WORDS_BIGENDIAN)
  61. // Allow ARM64 CRC32 instruction without a runtime check if
  62. // __ARM_FEATURE_CRC32 is defined. GCC and Clang only define this if the
  63. // proper compiler options are used.
  64. # if defined(__ARM_FEATURE_CRC32)
  65. # define CRC32_ARCH_OPTIMIZED 1
  66. # define CRC32_ARM64 1
  67. # elif defined(ARM64_RUNTIME_DETECTION)
  68. # define CRC32_ARCH_OPTIMIZED 1
  69. # define CRC32_ARM64 1
  70. # define CRC32_GENERIC 1
  71. # endif
  72. #endif
  73. #if defined(HAVE_USABLE_CLMUL)
  74. // If CLMUL is allowed unconditionally in the compiler options then the
  75. // generic version can be omitted. Note that this doesn't work with MSVC
  76. // as I don't know how to detect the features here.
  77. //
  78. // NOTE: Keep this in sync with the NO_CRC32_TABLE macro in crc32_table.c
  79. // and NO_CRC64_TABLE in crc64_table.c.
  80. # if (defined(__SSSE3__) && defined(__SSE4_1__) && defined(__PCLMUL__)) \
  81. || (defined(__e2k__) && __iset__ >= 6)
  82. # define CRC32_ARCH_OPTIMIZED 1
  83. # define CRC64_ARCH_OPTIMIZED 1
  84. # define CRC_X86_CLMUL 1
  85. # else
  86. # define CRC32_GENERIC 1
  87. # define CRC64_GENERIC 1
  88. # define CRC32_ARCH_OPTIMIZED 1
  89. # define CRC64_ARCH_OPTIMIZED 1
  90. # define CRC_X86_CLMUL 1
  91. /*
  92. // The generic code is much faster with 1-8-byte inputs and
  93. // has similar performance up to 16 bytes at least in
  94. // microbenchmarks (it depends on input buffer alignment
  95. // too). If both versions are built, this #define will use
  96. // the generic version for inputs up to 16 bytes and CLMUL
  97. // for bigger inputs. It saves a little in code size since
  98. // the special cases for 0-16-byte inputs will be omitted
  99. // from the CLMUL code.
  100. # define CRC_USE_GENERIC_FOR_SMALL_INPUTS 1
  101. */
  102. # endif
  103. #endif
  104. // For CRC32 use the generic slice-by-eight implementation if no optimized
  105. // version is available.
  106. #if !defined(CRC32_ARCH_OPTIMIZED) && !defined(CRC32_GENERIC)
  107. # define CRC32_GENERIC 1
  108. #endif
  109. // For CRC64 use the generic slice-by-four implementation if no optimized
  110. // version is available.
  111. #if !defined(CRC64_ARCH_OPTIMIZED) && !defined(CRC64_GENERIC)
  112. # define CRC64_GENERIC 1
  113. #endif
  114. #endif