mirror of
https://git.tukaani.org/xz.git
synced 2024-04-04 12:36:23 +02:00
5e78fcbf2e
Using the aligned methods requires more care to ensure that the address really is aligned, so it's nicer if the aligned methods are prefixed. The next commit will remove the unaligned_ prefix from the unaligned methods which in liblzma are used in more places than the aligned ones.
72 lines
1.6 KiB
C
72 lines
1.6 KiB
C
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
/// \file crc64.c
|
|
/// \brief CRC64 calculation
|
|
///
|
|
/// Calculate the CRC64 using the slice-by-four algorithm. This is the same
|
|
/// idea that is used in crc32_fast.c, but for CRC64 we use only four tables
|
|
/// instead of eight to avoid increasing CPU cache usage.
|
|
//
|
|
// Author: Lasse Collin
|
|
//
|
|
// This file has been put into the public domain.
|
|
// You can do whatever you want with this file.
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "check.h"
|
|
#include "crc_macros.h"
|
|
|
|
|
|
#ifdef WORDS_BIGENDIAN
|
|
# define A1(x) ((x) >> 56)
|
|
#else
|
|
# define A1 A
|
|
#endif
|
|
|
|
|
|
// See the comments in crc32_fast.c. They aren't duplicated here.
|
|
extern LZMA_API(uint64_t)
|
|
lzma_crc64(const uint8_t *buf, size_t size, uint64_t crc)
|
|
{
|
|
crc = ~crc;
|
|
|
|
#ifdef WORDS_BIGENDIAN
|
|
crc = bswap64(crc);
|
|
#endif
|
|
|
|
if (size > 4) {
|
|
while ((uintptr_t)(buf) & 3) {
|
|
crc = lzma_crc64_table[0][*buf++ ^ A1(crc)] ^ S8(crc);
|
|
--size;
|
|
}
|
|
|
|
const uint8_t *const limit = buf + (size & ~(size_t)(3));
|
|
size &= (size_t)(3);
|
|
|
|
while (buf < limit) {
|
|
#ifdef WORDS_BIGENDIAN
|
|
const uint32_t tmp = (crc >> 32)
|
|
^ aligned_read32ne(buf);
|
|
#else
|
|
const uint32_t tmp = crc ^ aligned_read32ne(buf);
|
|
#endif
|
|
buf += 4;
|
|
|
|
crc = lzma_crc64_table[3][A(tmp)]
|
|
^ lzma_crc64_table[2][B(tmp)]
|
|
^ S32(crc)
|
|
^ lzma_crc64_table[1][C(tmp)]
|
|
^ lzma_crc64_table[0][D(tmp)];
|
|
}
|
|
}
|
|
|
|
while (size-- != 0)
|
|
crc = lzma_crc64_table[0][*buf++ ^ A1(crc)] ^ S8(crc);
|
|
|
|
#ifdef WORDS_BIGENDIAN
|
|
crc = bswap64(crc);
|
|
#endif
|
|
|
|
return ~crc;
|
|
}
|