Coverage Report

Created: 2026-01-20 07:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/xz/src/liblzma/check/crc64_fast.c
Line
Count
Source
1
// SPDX-License-Identifier: 0BSD
2
3
///////////////////////////////////////////////////////////////////////////////
4
//
5
/// \file       crc64_fast.c
6
/// \brief      CRC64 calculation
7
//
8
//  Authors:    Lasse Collin
9
//              Ilya Kurdyukov
10
//
11
///////////////////////////////////////////////////////////////////////////////
12
13
#include "check.h"
14
#include "crc_common.h"
15
16
#if defined(CRC_X86_CLMUL)
17
# define BUILDING_CRC_CLMUL 64
18
# include "crc_x86_clmul.h"
19
#endif
20
21
22
#ifdef CRC64_GENERIC
23
24
/////////////////////////////////
25
// Generic slice-by-four CRC64 //
26
/////////////////////////////////
27
28
#if defined(WORDS_BIGENDIAN)
29
# include "crc64_table_be.h"
30
#else
31
# include "crc64_table_le.h"
32
#endif
33
34
35
#ifdef HAVE_CRC_X86_ASM
36
extern uint64_t lzma_crc64_generic(
37
    const uint8_t *buf, size_t size, uint64_t crc);
38
#else
39
40
#ifdef WORDS_BIGENDIAN
41
# define A1(x) ((x) >> 56)
42
#else
43
0
# define A1 A
44
#endif
45
46
47
// See the comments in crc32_fast.c. They aren't duplicated here.
48
static uint64_t
49
lzma_crc64_generic(const uint8_t *buf, size_t size, uint64_t crc)
50
0
{
51
0
  crc = ~crc;
52
53
#ifdef WORDS_BIGENDIAN
54
  crc = byteswap64(crc);
55
#endif
56
57
0
  if (size > 4) {
58
0
    while ((uintptr_t)(buf) & 3) {
59
0
      crc = lzma_crc64_table[0][*buf++ ^ A1(crc)] ^ S8(crc);
60
0
      --size;
61
0
    }
62
63
0
    const uint8_t *const limit = buf + (size & ~(size_t)(3));
64
0
    size &= (size_t)(3);
65
66
0
    while (buf < limit) {
67
#ifdef WORDS_BIGENDIAN
68
      const uint32_t tmp = (uint32_t)(crc >> 32)
69
          ^ aligned_read32ne(buf);
70
#else
71
0
      const uint32_t tmp = (uint32_t)crc
72
0
          ^ aligned_read32ne(buf);
73
0
#endif
74
0
      buf += 4;
75
76
0
      crc = lzma_crc64_table[3][A(tmp)]
77
0
          ^ lzma_crc64_table[2][B(tmp)]
78
0
          ^ S32(crc)
79
0
          ^ lzma_crc64_table[1][C(tmp)]
80
0
          ^ lzma_crc64_table[0][D(tmp)];
81
0
    }
82
0
  }
83
84
0
  while (size-- != 0)
85
0
    crc = lzma_crc64_table[0][*buf++ ^ A1(crc)] ^ S8(crc);
86
87
#ifdef WORDS_BIGENDIAN
88
  crc = byteswap64(crc);
89
#endif
90
91
0
  return ~crc;
92
0
}
93
#endif // HAVE_CRC_X86_ASM
94
#endif // CRC64_GENERIC
95
96
97
#if defined(CRC64_GENERIC) && defined(CRC64_ARCH_OPTIMIZED)
98
99
//////////////////////////
100
// Function dispatching //
101
//////////////////////////
102
103
// If both the generic and arch-optimized implementations are usable, then
104
// the function that is used is selected at runtime. See crc32_fast.c.
105
106
typedef uint64_t (*crc64_func_type)(
107
    const uint8_t *buf, size_t size, uint64_t crc);
108
109
static crc64_func_type
110
crc64_resolve(void)
111
252
{
112
252
  return is_arch_extension_supported()
113
252
      ? &crc64_arch_optimized : &lzma_crc64_generic;
114
252
}
115
116
#ifdef HAVE_FUNC_ATTRIBUTE_CONSTRUCTOR
117
# define CRC64_SET_FUNC_ATTR __attribute__((__constructor__))
118
static crc64_func_type crc64_func;
119
#else
120
# define CRC64_SET_FUNC_ATTR
121
static uint64_t crc64_dispatch(const uint8_t *buf, size_t size, uint64_t crc);
122
static crc64_func_type crc64_func = &crc64_dispatch;
123
#endif
124
125
126
CRC64_SET_FUNC_ATTR
127
static void
128
crc64_set_func(void)
129
252
{
130
252
  crc64_func = crc64_resolve();
131
252
  return;
132
252
}
133
134
135
#ifndef HAVE_FUNC_ATTRIBUTE_CONSTRUCTOR
136
static uint64_t
137
crc64_dispatch(const uint8_t *buf, size_t size, uint64_t crc)
138
{
139
  crc64_set_func();
140
  return crc64_func(buf, size, crc);
141
}
142
#endif
143
#endif
144
145
146
extern LZMA_API(uint64_t)
147
lzma_crc64(const uint8_t *buf, size_t size, uint64_t crc)
148
0
{
149
0
#if defined(CRC64_GENERIC) && defined(CRC64_ARCH_OPTIMIZED)
150
0
  return crc64_func(buf, size, crc);
151
152
#elif defined(CRC64_ARCH_OPTIMIZED)
153
  // If arch-optimized version is used unconditionally without runtime
154
  // CPU detection then omitting the generic version and its 8 KiB
155
  // lookup table makes the library smaller.
156
  return crc64_arch_optimized(buf, size, crc);
157
158
#else
159
  return lzma_crc64_generic(buf, size, crc);
160
#endif
161
0
}