12940b44dSPeter Avalos /////////////////////////////////////////////////////////////////////////////// 22940b44dSPeter Avalos // 32940b44dSPeter Avalos /// \file crc64.c 42940b44dSPeter Avalos /// \brief CRC64 calculation 52940b44dSPeter Avalos /// 62940b44dSPeter Avalos /// Calculate the CRC64 using the slice-by-four algorithm. This is the same 72940b44dSPeter Avalos /// idea that is used in crc32_fast.c, but for CRC64 we use only four tables 82940b44dSPeter Avalos /// instead of eight to avoid increasing CPU cache usage. 92940b44dSPeter Avalos // 102940b44dSPeter Avalos // Author: Lasse Collin 112940b44dSPeter Avalos // 122940b44dSPeter Avalos // This file has been put into the public domain. 132940b44dSPeter Avalos // You can do whatever you want with this file. 142940b44dSPeter Avalos // 152940b44dSPeter Avalos /////////////////////////////////////////////////////////////////////////////// 162940b44dSPeter Avalos 172940b44dSPeter Avalos #include "check.h" 182940b44dSPeter Avalos #include "crc_macros.h" 192940b44dSPeter Avalos 202940b44dSPeter Avalos 212940b44dSPeter Avalos #ifdef WORDS_BIGENDIAN 222940b44dSPeter Avalos # define A1(x) ((x) >> 56) 232940b44dSPeter Avalos #else 242940b44dSPeter Avalos # define A1 A 252940b44dSPeter Avalos #endif 262940b44dSPeter Avalos 272940b44dSPeter Avalos 282940b44dSPeter Avalos // See the comments in crc32_fast.c. They aren't duplicated here. 292940b44dSPeter Avalos extern LZMA_API(uint64_t) lzma_crc64(const uint8_t * buf,size_t size,uint64_t crc)302940b44dSPeter Avaloslzma_crc64(const uint8_t *buf, size_t size, uint64_t crc) 312940b44dSPeter Avalos { 322940b44dSPeter Avalos crc = ~crc; 332940b44dSPeter Avalos 342940b44dSPeter Avalos #ifdef WORDS_BIGENDIAN 352940b44dSPeter Avalos crc = bswap64(crc); 362940b44dSPeter Avalos #endif 372940b44dSPeter Avalos 382940b44dSPeter Avalos if (size > 4) { 392940b44dSPeter Avalos while ((uintptr_t)(buf) & 3) { 402940b44dSPeter Avalos crc = lzma_crc64_table[0][*buf++ ^ A1(crc)] ^ S8(crc); 412940b44dSPeter Avalos --size; 422940b44dSPeter Avalos } 432940b44dSPeter Avalos 442940b44dSPeter Avalos const uint8_t *const limit = buf + (size & ~(size_t)(3)); 452940b44dSPeter Avalos size &= (size_t)(3); 462940b44dSPeter Avalos 472940b44dSPeter Avalos while (buf < limit) { 482940b44dSPeter Avalos #ifdef WORDS_BIGENDIAN 492940b44dSPeter Avalos const uint32_t tmp = (crc >> 32) 50*e151908bSDaniel Fojt ^ aligned_read32ne(buf); 512940b44dSPeter Avalos #else 52*e151908bSDaniel Fojt const uint32_t tmp = crc ^ aligned_read32ne(buf); 532940b44dSPeter Avalos #endif 542940b44dSPeter Avalos buf += 4; 552940b44dSPeter Avalos 562940b44dSPeter Avalos crc = lzma_crc64_table[3][A(tmp)] 572940b44dSPeter Avalos ^ lzma_crc64_table[2][B(tmp)] 582940b44dSPeter Avalos ^ S32(crc) 592940b44dSPeter Avalos ^ lzma_crc64_table[1][C(tmp)] 602940b44dSPeter Avalos ^ lzma_crc64_table[0][D(tmp)]; 612940b44dSPeter Avalos } 622940b44dSPeter Avalos } 632940b44dSPeter Avalos 642940b44dSPeter Avalos while (size-- != 0) 652940b44dSPeter Avalos crc = lzma_crc64_table[0][*buf++ ^ A1(crc)] ^ S8(crc); 662940b44dSPeter Avalos 672940b44dSPeter Avalos #ifdef WORDS_BIGENDIAN 682940b44dSPeter Avalos crc = bswap64(crc); 692940b44dSPeter Avalos #endif 702940b44dSPeter Avalos 712940b44dSPeter Avalos return ~crc; 722940b44dSPeter Avalos } 73