1207753Smm/////////////////////////////////////////////////////////////////////////////// 2207753Smm// 3207753Smm/// \file crc64.c 4207753Smm/// \brief CRC64 calculation 5207753Smm/// 6207753Smm/// Calculate the CRC64 using the slice-by-four algorithm. This is the same 7207753Smm/// idea that is used in crc32_fast.c, but for CRC64 we use only four tables 8207753Smm/// instead of eight to avoid increasing CPU cache usage. 9207753Smm// 10207753Smm// Author: Lasse Collin 11207753Smm// 12207753Smm// This file has been put into the public domain. 13207753Smm// You can do whatever you want with this file. 14207753Smm// 15207753Smm/////////////////////////////////////////////////////////////////////////////// 16207753Smm 17207753Smm#include "check.h" 18207753Smm#include "crc_macros.h" 19207753Smm 20207753Smm 21207753Smm#ifdef WORDS_BIGENDIAN 22207753Smm# define A1(x) ((x) >> 56) 23207753Smm#else 24207753Smm# define A1 A 25207753Smm#endif 26207753Smm 27207753Smm 28207753Smm// See the comments in crc32_fast.c. They aren't duplicated here. 29207753Smmextern LZMA_API(uint64_t) 30207753Smmlzma_crc64(const uint8_t *buf, size_t size, uint64_t crc) 31207753Smm{ 32207753Smm crc = ~crc; 33207753Smm 34207753Smm#ifdef WORDS_BIGENDIAN 35207753Smm crc = bswap64(crc); 36207753Smm#endif 37207753Smm 38207753Smm if (size > 4) { 39207753Smm while ((uintptr_t)(buf) & 3) { 40207753Smm crc = lzma_crc64_table[0][*buf++ ^ A1(crc)] ^ S8(crc); 41207753Smm --size; 42207753Smm } 43207753Smm 44207753Smm const uint8_t *const limit = buf + (size & ~(size_t)(3)); 45207753Smm size &= (size_t)(3); 46207753Smm 47207753Smm while (buf < limit) { 48207753Smm#ifdef WORDS_BIGENDIAN 49207753Smm const uint32_t tmp = (crc >> 32) 50207753Smm ^ *(const uint32_t *)(buf); 51207753Smm#else 52207753Smm const uint32_t tmp = crc ^ *(const uint32_t *)(buf); 53207753Smm#endif 54207753Smm buf += 4; 55207753Smm 56207753Smm crc = lzma_crc64_table[3][A(tmp)] 57207753Smm ^ lzma_crc64_table[2][B(tmp)] 58207753Smm ^ S32(crc) 59207753Smm ^ lzma_crc64_table[1][C(tmp)] 60207753Smm ^ lzma_crc64_table[0][D(tmp)]; 61207753Smm } 62207753Smm } 63207753Smm 64207753Smm while (size-- != 0) 65207753Smm crc = lzma_crc64_table[0][*buf++ ^ A1(crc)] ^ S8(crc); 66207753Smm 67207753Smm#ifdef WORDS_BIGENDIAN 68207753Smm crc = bswap64(crc); 69207753Smm#endif 70207753Smm 71207753Smm return ~crc; 72207753Smm} 73