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