crc64_fast.c 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. /// \file crc64.c
  4. /// \brief CRC64 calculation
  5. ///
  6. /// Calculate the CRC64 using the slice-by-four algorithm. This is the same
  7. /// idea that is used in crc32_fast.c, but for CRC64 we use only four tables
  8. /// instead of eight to avoid increasing CPU cache usage.
  9. //
  10. // Author: Lasse Collin
  11. //
  12. // This file has been put into the public domain.
  13. // You can do whatever you want with this file.
  14. //
  15. ///////////////////////////////////////////////////////////////////////////////
  16. #include "check.h"
  17. #include "crc_macros.h"
  18. #ifdef WORDS_BIGENDIAN
  19. # define A1(x) ((x) >> 56)
  20. #else
  21. # define A1 A
  22. #endif
  23. // See the comments in crc32_fast.c. They aren't duplicated here.
  24. extern LZMA_API(uint64_t)
  25. lzma_crc64(const uint8_t *buf, size_t size, uint64_t crc)
  26. {
  27. crc = ~crc;
  28. #ifdef WORDS_BIGENDIAN
  29. crc = bswap64(crc);
  30. #endif
  31. if (size > 4) {
  32. while ((uintptr_t)(buf) & 3) {
  33. crc = lzma_crc64_table[0][*buf++ ^ A1(crc)] ^ S8(crc);
  34. --size;
  35. }
  36. const uint8_t *const limit = buf + (size & ~(size_t)(3));
  37. size &= (size_t)(3);
  38. while (buf < limit) {
  39. #ifdef WORDS_BIGENDIAN
  40. const uint32_t tmp = (crc >> 32)
  41. ^ *(const uint32_t *)(buf);
  42. #else
  43. const uint32_t tmp = crc ^ *(const uint32_t *)(buf);
  44. #endif
  45. buf += 4;
  46. crc = lzma_crc64_table[3][A(tmp)]
  47. ^ lzma_crc64_table[2][B(tmp)]
  48. ^ S32(crc)
  49. ^ lzma_crc64_table[1][C(tmp)]
  50. ^ lzma_crc64_table[0][D(tmp)];
  51. }
  52. }
  53. while (size-- != 0)
  54. crc = lzma_crc64_table[0][*buf++ ^ A1(crc)] ^ S8(crc);
  55. #ifdef WORDS_BIGENDIAN
  56. crc = bswap64(crc);
  57. #endif
  58. return ~crc;
  59. }