]> icculus.org git repositories - icculus/xz.git/blob - src/liblzma/check/crc64.c
Imported to git.
[icculus/xz.git] / src / liblzma / check / crc64.c
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 /// \file       crc64.c
4 /// \brief      CRC64 calculation
5 //
6 //  This code has been put into the public domain.
7 //
8 //  This library is distributed in the hope that it will be useful,
9 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 //
12 ///////////////////////////////////////////////////////////////////////////////
13
14 #include "check.h"
15 #include "crc_macros.h"
16
17
18 #ifdef WORDS_BIGENDIAN
19 #       define A1(x) ((x) >> 56)
20 #else
21 #       define A1 A
22 #endif
23
24
25 // See comments in crc32.c.
26 extern uint64_t
27 lzma_crc64(const uint8_t *buf, size_t size, uint64_t crc)
28 {
29         crc = ~crc;
30
31 #ifdef WORDS_BIGENDIAN
32         crc = bswap_64(crc);
33 #endif
34
35         if (size > 4) {
36                 while ((uintptr_t)(buf) & 3) {
37                         crc = lzma_crc64_table[0][*buf++ ^ A1(crc)] ^ S8(crc);
38                         --size;
39                 }
40
41                 const uint8_t *const limit = buf + (size & ~(size_t)(3));
42                 size &= (size_t)(3);
43
44                 // Calculate the CRC64 using the slice-by-four algorithm.
45                 //
46                 // In contrast to CRC32 code, this one seems to be fastest
47                 // with -O3 -fomit-frame-pointer.
48                 while (buf < limit) {
49 #ifdef WORDS_BIGENDIAN
50                         const uint32_t tmp = (crc >> 32) ^ *(uint32_t *)(buf);
51 #else
52                         const uint32_t tmp = crc ^ *(uint32_t *)(buf);
53 #endif
54                         buf += 4;
55
56                         // It is critical for performance, that
57                         // the crc variable is XORed between the
58                         // two table-lookup pairs.
59                         crc = lzma_crc64_table[3][A(tmp)]
60                             ^ lzma_crc64_table[2][B(tmp)]
61                             ^ S32(crc)
62                             ^ lzma_crc64_table[1][C(tmp)]
63                             ^ lzma_crc64_table[0][D(tmp)];
64                 }
65         }
66
67         while (size-- != 0)
68                 crc = lzma_crc64_table[0][*buf++ ^ A1(crc)] ^ S8(crc);
69
70 #ifdef WORDS_BIGENDIAN
71         crc = bswap_64(crc);
72 #endif
73
74         return ~crc;
75 }