1e0c1b49fSNick Terrell /*
2e0c1b49fSNick Terrell * Copyright (c) Yann Collet, Facebook, Inc.
3e0c1b49fSNick Terrell * All rights reserved.
4e0c1b49fSNick Terrell *
5e0c1b49fSNick Terrell * This source code is licensed under both the BSD-style license (found in the
6e0c1b49fSNick Terrell * LICENSE file in the root directory of this source tree) and the GPLv2 (found
7e0c1b49fSNick Terrell * in the COPYING file in the root directory of this source tree).
8e0c1b49fSNick Terrell * You may select, at your option, one of the above-listed licenses.
9e0c1b49fSNick Terrell */
10e0c1b49fSNick Terrell
11e0c1b49fSNick Terrell #ifndef ZSTD_CCOMMON_H_MODULE
12e0c1b49fSNick Terrell #define ZSTD_CCOMMON_H_MODULE
13e0c1b49fSNick Terrell
14e0c1b49fSNick Terrell /* this module contains definitions which must be identical
15e0c1b49fSNick Terrell * across compression, decompression and dictBuilder.
16e0c1b49fSNick Terrell * It also contains a few functions useful to at least 2 of them
17e0c1b49fSNick Terrell * and which benefit from being inlined */
18e0c1b49fSNick Terrell
19e0c1b49fSNick Terrell /*-*************************************
20e0c1b49fSNick Terrell * Dependencies
21e0c1b49fSNick Terrell ***************************************/
22e0c1b49fSNick Terrell #include "compiler.h"
23*2aa14b1aSNick Terrell #include "cpu.h"
24e0c1b49fSNick Terrell #include "mem.h"
25e0c1b49fSNick Terrell #include "debug.h" /* assert, DEBUGLOG, RAWLOG, g_debuglevel */
26e0c1b49fSNick Terrell #include "error_private.h"
27e0c1b49fSNick Terrell #define ZSTD_STATIC_LINKING_ONLY
28e0c1b49fSNick Terrell #include <linux/zstd.h>
29e0c1b49fSNick Terrell #define FSE_STATIC_LINKING_ONLY
30e0c1b49fSNick Terrell #include "fse.h"
31e0c1b49fSNick Terrell #define HUF_STATIC_LINKING_ONLY
32e0c1b49fSNick Terrell #include "huf.h"
33e0c1b49fSNick Terrell #include <linux/xxhash.h> /* XXH_reset, update, digest */
34e0c1b49fSNick Terrell #define ZSTD_TRACE 0
35e0c1b49fSNick Terrell
36e0c1b49fSNick Terrell
37e0c1b49fSNick Terrell /* ---- static assert (debug) --- */
38e0c1b49fSNick Terrell #define ZSTD_STATIC_ASSERT(c) DEBUG_STATIC_ASSERT(c)
39e0c1b49fSNick Terrell #define ZSTD_isError ERR_isError /* for inlining */
40e0c1b49fSNick Terrell #define FSE_isError ERR_isError
41e0c1b49fSNick Terrell #define HUF_isError ERR_isError
42e0c1b49fSNick Terrell
43e0c1b49fSNick Terrell
44e0c1b49fSNick Terrell /*-*************************************
45e0c1b49fSNick Terrell * shared macros
46e0c1b49fSNick Terrell ***************************************/
47e0c1b49fSNick Terrell #undef MIN
48e0c1b49fSNick Terrell #undef MAX
49e0c1b49fSNick Terrell #define MIN(a,b) ((a)<(b) ? (a) : (b))
50e0c1b49fSNick Terrell #define MAX(a,b) ((a)>(b) ? (a) : (b))
51*2aa14b1aSNick Terrell #define BOUNDED(min,val,max) (MAX(min,MIN(val,max)))
52e0c1b49fSNick Terrell
53e0c1b49fSNick Terrell
54e0c1b49fSNick Terrell /*-*************************************
55e0c1b49fSNick Terrell * Common constants
56e0c1b49fSNick Terrell ***************************************/
57e0c1b49fSNick Terrell #define ZSTD_OPT_NUM (1<<12)
58e0c1b49fSNick Terrell
59e0c1b49fSNick Terrell #define ZSTD_REP_NUM 3 /* number of repcodes */
60e0c1b49fSNick Terrell static UNUSED_ATTR const U32 repStartValue[ZSTD_REP_NUM] = { 1, 4, 8 };
61e0c1b49fSNick Terrell
62e0c1b49fSNick Terrell #define KB *(1 <<10)
63e0c1b49fSNick Terrell #define MB *(1 <<20)
64e0c1b49fSNick Terrell #define GB *(1U<<30)
65e0c1b49fSNick Terrell
66e0c1b49fSNick Terrell #define BIT7 128
67e0c1b49fSNick Terrell #define BIT6 64
68e0c1b49fSNick Terrell #define BIT5 32
69e0c1b49fSNick Terrell #define BIT4 16
70e0c1b49fSNick Terrell #define BIT1 2
71e0c1b49fSNick Terrell #define BIT0 1
72e0c1b49fSNick Terrell
73e0c1b49fSNick Terrell #define ZSTD_WINDOWLOG_ABSOLUTEMIN 10
74e0c1b49fSNick Terrell static UNUSED_ATTR const size_t ZSTD_fcs_fieldSize[4] = { 0, 2, 4, 8 };
75e0c1b49fSNick Terrell static UNUSED_ATTR const size_t ZSTD_did_fieldSize[4] = { 0, 1, 2, 4 };
76e0c1b49fSNick Terrell
77e0c1b49fSNick Terrell #define ZSTD_FRAMEIDSIZE 4 /* magic number size */
78e0c1b49fSNick Terrell
79e0c1b49fSNick Terrell #define ZSTD_BLOCKHEADERSIZE 3 /* C standard doesn't allow `static const` variable to be init using another `static const` variable */
80e0c1b49fSNick Terrell static UNUSED_ATTR const size_t ZSTD_blockHeaderSize = ZSTD_BLOCKHEADERSIZE;
81e0c1b49fSNick Terrell typedef enum { bt_raw, bt_rle, bt_compressed, bt_reserved } blockType_e;
82e0c1b49fSNick Terrell
83e0c1b49fSNick Terrell #define ZSTD_FRAMECHECKSUMSIZE 4
84e0c1b49fSNick Terrell
85e0c1b49fSNick Terrell #define MIN_SEQUENCES_SIZE 1 /* nbSeq==0 */
86e0c1b49fSNick Terrell #define MIN_CBLOCK_SIZE (1 /*litCSize*/ + 1 /* RLE or RAW */ + MIN_SEQUENCES_SIZE /* nbSeq==0 */) /* for a non-null block */
87e0c1b49fSNick Terrell
88e0c1b49fSNick Terrell #define HufLog 12
89e0c1b49fSNick Terrell typedef enum { set_basic, set_rle, set_compressed, set_repeat } symbolEncodingType_e;
90e0c1b49fSNick Terrell
91e0c1b49fSNick Terrell #define LONGNBSEQ 0x7F00
92e0c1b49fSNick Terrell
93e0c1b49fSNick Terrell #define MINMATCH 3
94e0c1b49fSNick Terrell
95e0c1b49fSNick Terrell #define Litbits 8
96e0c1b49fSNick Terrell #define MaxLit ((1<<Litbits) - 1)
97e0c1b49fSNick Terrell #define MaxML 52
98e0c1b49fSNick Terrell #define MaxLL 35
99e0c1b49fSNick Terrell #define DefaultMaxOff 28
100e0c1b49fSNick Terrell #define MaxOff 31
101e0c1b49fSNick Terrell #define MaxSeq MAX(MaxLL, MaxML) /* Assumption : MaxOff < MaxLL,MaxML */
102e0c1b49fSNick Terrell #define MLFSELog 9
103e0c1b49fSNick Terrell #define LLFSELog 9
104e0c1b49fSNick Terrell #define OffFSELog 8
105e0c1b49fSNick Terrell #define MaxFSELog MAX(MAX(MLFSELog, LLFSELog), OffFSELog)
106e0c1b49fSNick Terrell
107e0c1b49fSNick Terrell #define ZSTD_MAX_HUF_HEADER_SIZE 128 /* header + <= 127 byte tree description */
108e0c1b49fSNick Terrell /* Each table cannot take more than #symbols * FSELog bits */
109e0c1b49fSNick Terrell #define ZSTD_MAX_FSE_HEADERS_SIZE (((MaxML + 1) * MLFSELog + (MaxLL + 1) * LLFSELog + (MaxOff + 1) * OffFSELog + 7) / 8)
110e0c1b49fSNick Terrell
111*2aa14b1aSNick Terrell static UNUSED_ATTR const U8 LL_bits[MaxLL+1] = {
112e0c1b49fSNick Terrell 0, 0, 0, 0, 0, 0, 0, 0,
113e0c1b49fSNick Terrell 0, 0, 0, 0, 0, 0, 0, 0,
114e0c1b49fSNick Terrell 1, 1, 1, 1, 2, 2, 3, 3,
115e0c1b49fSNick Terrell 4, 6, 7, 8, 9,10,11,12,
116e0c1b49fSNick Terrell 13,14,15,16
117e0c1b49fSNick Terrell };
118e0c1b49fSNick Terrell static UNUSED_ATTR const S16 LL_defaultNorm[MaxLL+1] = {
119e0c1b49fSNick Terrell 4, 3, 2, 2, 2, 2, 2, 2,
120e0c1b49fSNick Terrell 2, 2, 2, 2, 2, 1, 1, 1,
121e0c1b49fSNick Terrell 2, 2, 2, 2, 2, 2, 2, 2,
122e0c1b49fSNick Terrell 2, 3, 2, 1, 1, 1, 1, 1,
123e0c1b49fSNick Terrell -1,-1,-1,-1
124e0c1b49fSNick Terrell };
125e0c1b49fSNick Terrell #define LL_DEFAULTNORMLOG 6 /* for static allocation */
126e0c1b49fSNick Terrell static UNUSED_ATTR const U32 LL_defaultNormLog = LL_DEFAULTNORMLOG;
127e0c1b49fSNick Terrell
128*2aa14b1aSNick Terrell static UNUSED_ATTR const U8 ML_bits[MaxML+1] = {
129e0c1b49fSNick Terrell 0, 0, 0, 0, 0, 0, 0, 0,
130e0c1b49fSNick Terrell 0, 0, 0, 0, 0, 0, 0, 0,
131e0c1b49fSNick Terrell 0, 0, 0, 0, 0, 0, 0, 0,
132e0c1b49fSNick Terrell 0, 0, 0, 0, 0, 0, 0, 0,
133e0c1b49fSNick Terrell 1, 1, 1, 1, 2, 2, 3, 3,
134e0c1b49fSNick Terrell 4, 4, 5, 7, 8, 9,10,11,
135e0c1b49fSNick Terrell 12,13,14,15,16
136e0c1b49fSNick Terrell };
137e0c1b49fSNick Terrell static UNUSED_ATTR const S16 ML_defaultNorm[MaxML+1] = {
138e0c1b49fSNick Terrell 1, 4, 3, 2, 2, 2, 2, 2,
139e0c1b49fSNick Terrell 2, 1, 1, 1, 1, 1, 1, 1,
140e0c1b49fSNick Terrell 1, 1, 1, 1, 1, 1, 1, 1,
141e0c1b49fSNick Terrell 1, 1, 1, 1, 1, 1, 1, 1,
142e0c1b49fSNick Terrell 1, 1, 1, 1, 1, 1, 1, 1,
143e0c1b49fSNick Terrell 1, 1, 1, 1, 1, 1,-1,-1,
144e0c1b49fSNick Terrell -1,-1,-1,-1,-1
145e0c1b49fSNick Terrell };
146e0c1b49fSNick Terrell #define ML_DEFAULTNORMLOG 6 /* for static allocation */
147e0c1b49fSNick Terrell static UNUSED_ATTR const U32 ML_defaultNormLog = ML_DEFAULTNORMLOG;
148e0c1b49fSNick Terrell
149e0c1b49fSNick Terrell static UNUSED_ATTR const S16 OF_defaultNorm[DefaultMaxOff+1] = {
150e0c1b49fSNick Terrell 1, 1, 1, 1, 1, 1, 2, 2,
151e0c1b49fSNick Terrell 2, 1, 1, 1, 1, 1, 1, 1,
152e0c1b49fSNick Terrell 1, 1, 1, 1, 1, 1, 1, 1,
153e0c1b49fSNick Terrell -1,-1,-1,-1,-1
154e0c1b49fSNick Terrell };
155e0c1b49fSNick Terrell #define OF_DEFAULTNORMLOG 5 /* for static allocation */
156e0c1b49fSNick Terrell static UNUSED_ATTR const U32 OF_defaultNormLog = OF_DEFAULTNORMLOG;
157e0c1b49fSNick Terrell
158e0c1b49fSNick Terrell
159e0c1b49fSNick Terrell /*-*******************************************
160e0c1b49fSNick Terrell * Shared functions to include for inlining
161e0c1b49fSNick Terrell *********************************************/
ZSTD_copy8(void * dst,const void * src)162e0c1b49fSNick Terrell static void ZSTD_copy8(void* dst, const void* src) {
163*2aa14b1aSNick Terrell #if defined(ZSTD_ARCH_ARM_NEON)
164*2aa14b1aSNick Terrell vst1_u8((uint8_t*)dst, vld1_u8((const uint8_t*)src));
165*2aa14b1aSNick Terrell #else
166e0c1b49fSNick Terrell ZSTD_memcpy(dst, src, 8);
167*2aa14b1aSNick Terrell #endif
168e0c1b49fSNick Terrell }
169e0c1b49fSNick Terrell #define COPY8(d,s) { ZSTD_copy8(d,s); d+=8; s+=8; }
170*2aa14b1aSNick Terrell
171*2aa14b1aSNick Terrell /* Need to use memmove here since the literal buffer can now be located within
172*2aa14b1aSNick Terrell the dst buffer. In circumstances where the op "catches up" to where the
173*2aa14b1aSNick Terrell literal buffer is, there can be partial overlaps in this call on the final
174*2aa14b1aSNick Terrell copy if the literal is being shifted by less than 16 bytes. */
ZSTD_copy16(void * dst,const void * src)175e0c1b49fSNick Terrell static void ZSTD_copy16(void* dst, const void* src) {
176*2aa14b1aSNick Terrell #if defined(ZSTD_ARCH_ARM_NEON)
177*2aa14b1aSNick Terrell vst1q_u8((uint8_t*)dst, vld1q_u8((const uint8_t*)src));
178*2aa14b1aSNick Terrell #elif defined(ZSTD_ARCH_X86_SSE2)
179*2aa14b1aSNick Terrell _mm_storeu_si128((__m128i*)dst, _mm_loadu_si128((const __m128i*)src));
180*2aa14b1aSNick Terrell #elif defined(__clang__)
181*2aa14b1aSNick Terrell ZSTD_memmove(dst, src, 16);
182*2aa14b1aSNick Terrell #else
183*2aa14b1aSNick Terrell /* ZSTD_memmove is not inlined properly by gcc */
184*2aa14b1aSNick Terrell BYTE copy16_buf[16];
185*2aa14b1aSNick Terrell ZSTD_memcpy(copy16_buf, src, 16);
186*2aa14b1aSNick Terrell ZSTD_memcpy(dst, copy16_buf, 16);
187*2aa14b1aSNick Terrell #endif
188e0c1b49fSNick Terrell }
189e0c1b49fSNick Terrell #define COPY16(d,s) { ZSTD_copy16(d,s); d+=16; s+=16; }
190e0c1b49fSNick Terrell
191e0c1b49fSNick Terrell #define WILDCOPY_OVERLENGTH 32
192e0c1b49fSNick Terrell #define WILDCOPY_VECLEN 16
193e0c1b49fSNick Terrell
194e0c1b49fSNick Terrell typedef enum {
195e0c1b49fSNick Terrell ZSTD_no_overlap,
196e0c1b49fSNick Terrell ZSTD_overlap_src_before_dst
197e0c1b49fSNick Terrell /* ZSTD_overlap_dst_before_src, */
198e0c1b49fSNick Terrell } ZSTD_overlap_e;
199e0c1b49fSNick Terrell
200e0c1b49fSNick Terrell /*! ZSTD_wildcopy() :
201e0c1b49fSNick Terrell * Custom version of ZSTD_memcpy(), can over read/write up to WILDCOPY_OVERLENGTH bytes (if length==0)
202e0c1b49fSNick Terrell * @param ovtype controls the overlap detection
203e0c1b49fSNick Terrell * - ZSTD_no_overlap: The source and destination are guaranteed to be at least WILDCOPY_VECLEN bytes apart.
204e0c1b49fSNick Terrell * - ZSTD_overlap_src_before_dst: The src and dst may overlap, but they MUST be at least 8 bytes apart.
205e0c1b49fSNick Terrell * The src buffer must be before the dst buffer.
206e0c1b49fSNick Terrell */
207e0c1b49fSNick Terrell MEM_STATIC FORCE_INLINE_ATTR
ZSTD_wildcopy(void * dst,const void * src,ptrdiff_t length,ZSTD_overlap_e const ovtype)208e0c1b49fSNick Terrell void ZSTD_wildcopy(void* dst, const void* src, ptrdiff_t length, ZSTD_overlap_e const ovtype)
209e0c1b49fSNick Terrell {
210e0c1b49fSNick Terrell ptrdiff_t diff = (BYTE*)dst - (const BYTE*)src;
211e0c1b49fSNick Terrell const BYTE* ip = (const BYTE*)src;
212e0c1b49fSNick Terrell BYTE* op = (BYTE*)dst;
213e0c1b49fSNick Terrell BYTE* const oend = op + length;
214e0c1b49fSNick Terrell
215e0c1b49fSNick Terrell if (ovtype == ZSTD_overlap_src_before_dst && diff < WILDCOPY_VECLEN) {
216e0c1b49fSNick Terrell /* Handle short offset copies. */
217e0c1b49fSNick Terrell do {
218e0c1b49fSNick Terrell COPY8(op, ip)
219e0c1b49fSNick Terrell } while (op < oend);
220e0c1b49fSNick Terrell } else {
221e0c1b49fSNick Terrell assert(diff >= WILDCOPY_VECLEN || diff <= -WILDCOPY_VECLEN);
222e0c1b49fSNick Terrell /* Separate out the first COPY16() call because the copy length is
223e0c1b49fSNick Terrell * almost certain to be short, so the branches have different
224e0c1b49fSNick Terrell * probabilities. Since it is almost certain to be short, only do
225e0c1b49fSNick Terrell * one COPY16() in the first call. Then, do two calls per loop since
226e0c1b49fSNick Terrell * at that point it is more likely to have a high trip count.
227e0c1b49fSNick Terrell */
228e0c1b49fSNick Terrell #ifdef __aarch64__
229e0c1b49fSNick Terrell do {
230e0c1b49fSNick Terrell COPY16(op, ip);
231e0c1b49fSNick Terrell }
232e0c1b49fSNick Terrell while (op < oend);
233e0c1b49fSNick Terrell #else
234e0c1b49fSNick Terrell ZSTD_copy16(op, ip);
235e0c1b49fSNick Terrell if (16 >= length) return;
236e0c1b49fSNick Terrell op += 16;
237e0c1b49fSNick Terrell ip += 16;
238e0c1b49fSNick Terrell do {
239e0c1b49fSNick Terrell COPY16(op, ip);
240e0c1b49fSNick Terrell COPY16(op, ip);
241e0c1b49fSNick Terrell }
242e0c1b49fSNick Terrell while (op < oend);
243e0c1b49fSNick Terrell #endif
244e0c1b49fSNick Terrell }
245e0c1b49fSNick Terrell }
246e0c1b49fSNick Terrell
ZSTD_limitCopy(void * dst,size_t dstCapacity,const void * src,size_t srcSize)247e0c1b49fSNick Terrell MEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
248e0c1b49fSNick Terrell {
249e0c1b49fSNick Terrell size_t const length = MIN(dstCapacity, srcSize);
250e0c1b49fSNick Terrell if (length > 0) {
251e0c1b49fSNick Terrell ZSTD_memcpy(dst, src, length);
252e0c1b49fSNick Terrell }
253e0c1b49fSNick Terrell return length;
254e0c1b49fSNick Terrell }
255e0c1b49fSNick Terrell
256e0c1b49fSNick Terrell /* define "workspace is too large" as this number of times larger than needed */
257e0c1b49fSNick Terrell #define ZSTD_WORKSPACETOOLARGE_FACTOR 3
258e0c1b49fSNick Terrell
259e0c1b49fSNick Terrell /* when workspace is continuously too large
260e0c1b49fSNick Terrell * during at least this number of times,
261e0c1b49fSNick Terrell * context's memory usage is considered wasteful,
262e0c1b49fSNick Terrell * because it's sized to handle a worst case scenario which rarely happens.
263e0c1b49fSNick Terrell * In which case, resize it down to free some memory */
264e0c1b49fSNick Terrell #define ZSTD_WORKSPACETOOLARGE_MAXDURATION 128
265e0c1b49fSNick Terrell
266e0c1b49fSNick Terrell /* Controls whether the input/output buffer is buffered or stable. */
267e0c1b49fSNick Terrell typedef enum {
268e0c1b49fSNick Terrell ZSTD_bm_buffered = 0, /* Buffer the input/output */
269e0c1b49fSNick Terrell ZSTD_bm_stable = 1 /* ZSTD_inBuffer/ZSTD_outBuffer is stable */
270e0c1b49fSNick Terrell } ZSTD_bufferMode_e;
271e0c1b49fSNick Terrell
272e0c1b49fSNick Terrell
273e0c1b49fSNick Terrell /*-*******************************************
274e0c1b49fSNick Terrell * Private declarations
275e0c1b49fSNick Terrell *********************************************/
276e0c1b49fSNick Terrell typedef struct seqDef_s {
277*2aa14b1aSNick Terrell U32 offBase; /* offBase == Offset + ZSTD_REP_NUM, or repcode 1,2,3 */
278e0c1b49fSNick Terrell U16 litLength;
279*2aa14b1aSNick Terrell U16 mlBase; /* mlBase == matchLength - MINMATCH */
280e0c1b49fSNick Terrell } seqDef;
281e0c1b49fSNick Terrell
282*2aa14b1aSNick Terrell /* Controls whether seqStore has a single "long" litLength or matchLength. See seqStore_t. */
283*2aa14b1aSNick Terrell typedef enum {
284*2aa14b1aSNick Terrell ZSTD_llt_none = 0, /* no longLengthType */
285*2aa14b1aSNick Terrell ZSTD_llt_literalLength = 1, /* represents a long literal */
286*2aa14b1aSNick Terrell ZSTD_llt_matchLength = 2 /* represents a long match */
287*2aa14b1aSNick Terrell } ZSTD_longLengthType_e;
288*2aa14b1aSNick Terrell
289e0c1b49fSNick Terrell typedef struct {
290e0c1b49fSNick Terrell seqDef* sequencesStart;
291e0c1b49fSNick Terrell seqDef* sequences; /* ptr to end of sequences */
292e0c1b49fSNick Terrell BYTE* litStart;
293e0c1b49fSNick Terrell BYTE* lit; /* ptr to end of literals */
294e0c1b49fSNick Terrell BYTE* llCode;
295e0c1b49fSNick Terrell BYTE* mlCode;
296e0c1b49fSNick Terrell BYTE* ofCode;
297e0c1b49fSNick Terrell size_t maxNbSeq;
298e0c1b49fSNick Terrell size_t maxNbLit;
299e0c1b49fSNick Terrell
300*2aa14b1aSNick Terrell /* longLengthPos and longLengthType to allow us to represent either a single litLength or matchLength
301e0c1b49fSNick Terrell * in the seqStore that has a value larger than U16 (if it exists). To do so, we increment
302e0c1b49fSNick Terrell * the existing value of the litLength or matchLength by 0x10000.
303e0c1b49fSNick Terrell */
304*2aa14b1aSNick Terrell ZSTD_longLengthType_e longLengthType;
305e0c1b49fSNick Terrell U32 longLengthPos; /* Index of the sequence to apply long length modification to */
306e0c1b49fSNick Terrell } seqStore_t;
307e0c1b49fSNick Terrell
308e0c1b49fSNick Terrell typedef struct {
309e0c1b49fSNick Terrell U32 litLength;
310e0c1b49fSNick Terrell U32 matchLength;
311e0c1b49fSNick Terrell } ZSTD_sequenceLength;
312e0c1b49fSNick Terrell
313e0c1b49fSNick Terrell /*
314e0c1b49fSNick Terrell * Returns the ZSTD_sequenceLength for the given sequences. It handles the decoding of long sequences
315*2aa14b1aSNick Terrell * indicated by longLengthPos and longLengthType, and adds MINMATCH back to matchLength.
316e0c1b49fSNick Terrell */
ZSTD_getSequenceLength(seqStore_t const * seqStore,seqDef const * seq)317e0c1b49fSNick Terrell MEM_STATIC ZSTD_sequenceLength ZSTD_getSequenceLength(seqStore_t const* seqStore, seqDef const* seq)
318e0c1b49fSNick Terrell {
319e0c1b49fSNick Terrell ZSTD_sequenceLength seqLen;
320e0c1b49fSNick Terrell seqLen.litLength = seq->litLength;
321*2aa14b1aSNick Terrell seqLen.matchLength = seq->mlBase + MINMATCH;
322e0c1b49fSNick Terrell if (seqStore->longLengthPos == (U32)(seq - seqStore->sequencesStart)) {
323*2aa14b1aSNick Terrell if (seqStore->longLengthType == ZSTD_llt_literalLength) {
324e0c1b49fSNick Terrell seqLen.litLength += 0xFFFF;
325e0c1b49fSNick Terrell }
326*2aa14b1aSNick Terrell if (seqStore->longLengthType == ZSTD_llt_matchLength) {
327e0c1b49fSNick Terrell seqLen.matchLength += 0xFFFF;
328e0c1b49fSNick Terrell }
329e0c1b49fSNick Terrell }
330e0c1b49fSNick Terrell return seqLen;
331e0c1b49fSNick Terrell }
332e0c1b49fSNick Terrell
333e0c1b49fSNick Terrell /*
334e0c1b49fSNick Terrell * Contains the compressed frame size and an upper-bound for the decompressed frame size.
335e0c1b49fSNick Terrell * Note: before using `compressedSize`, check for errors using ZSTD_isError().
336e0c1b49fSNick Terrell * similarly, before using `decompressedBound`, check for errors using:
337e0c1b49fSNick Terrell * `decompressedBound != ZSTD_CONTENTSIZE_ERROR`
338e0c1b49fSNick Terrell */
339e0c1b49fSNick Terrell typedef struct {
340e0c1b49fSNick Terrell size_t compressedSize;
341e0c1b49fSNick Terrell unsigned long long decompressedBound;
342e0c1b49fSNick Terrell } ZSTD_frameSizeInfo; /* decompress & legacy */
343e0c1b49fSNick Terrell
344e0c1b49fSNick Terrell const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx); /* compress & dictBuilder */
345e0c1b49fSNick Terrell void ZSTD_seqToCodes(const seqStore_t* seqStorePtr); /* compress, dictBuilder, decodeCorpus (shouldn't get its definition from here) */
346e0c1b49fSNick Terrell
347e0c1b49fSNick Terrell /* custom memory allocation functions */
348e0c1b49fSNick Terrell void* ZSTD_customMalloc(size_t size, ZSTD_customMem customMem);
349e0c1b49fSNick Terrell void* ZSTD_customCalloc(size_t size, ZSTD_customMem customMem);
350e0c1b49fSNick Terrell void ZSTD_customFree(void* ptr, ZSTD_customMem customMem);
351e0c1b49fSNick Terrell
352e0c1b49fSNick Terrell
ZSTD_highbit32(U32 val)353e0c1b49fSNick Terrell MEM_STATIC U32 ZSTD_highbit32(U32 val) /* compress, dictBuilder, decodeCorpus */
354e0c1b49fSNick Terrell {
355e0c1b49fSNick Terrell assert(val != 0);
356e0c1b49fSNick Terrell {
357e0c1b49fSNick Terrell # if (__GNUC__ >= 3) /* GCC Intrinsic */
358e0c1b49fSNick Terrell return __builtin_clz (val) ^ 31;
359e0c1b49fSNick Terrell # else /* Software version */
360e0c1b49fSNick Terrell static const U32 DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 };
361e0c1b49fSNick Terrell U32 v = val;
362e0c1b49fSNick Terrell v |= v >> 1;
363e0c1b49fSNick Terrell v |= v >> 2;
364e0c1b49fSNick Terrell v |= v >> 4;
365e0c1b49fSNick Terrell v |= v >> 8;
366e0c1b49fSNick Terrell v |= v >> 16;
367e0c1b49fSNick Terrell return DeBruijnClz[(v * 0x07C4ACDDU) >> 27];
368e0c1b49fSNick Terrell # endif
369e0c1b49fSNick Terrell }
370e0c1b49fSNick Terrell }
371e0c1b49fSNick Terrell
372*2aa14b1aSNick Terrell /*
373*2aa14b1aSNick Terrell * Counts the number of trailing zeros of a `size_t`.
374*2aa14b1aSNick Terrell * Most compilers should support CTZ as a builtin. A backup
375*2aa14b1aSNick Terrell * implementation is provided if the builtin isn't supported, but
376*2aa14b1aSNick Terrell * it may not be terribly efficient.
377*2aa14b1aSNick Terrell */
ZSTD_countTrailingZeros(size_t val)378*2aa14b1aSNick Terrell MEM_STATIC unsigned ZSTD_countTrailingZeros(size_t val)
379*2aa14b1aSNick Terrell {
380*2aa14b1aSNick Terrell if (MEM_64bits()) {
381*2aa14b1aSNick Terrell # if (__GNUC__ >= 4)
382*2aa14b1aSNick Terrell return __builtin_ctzll((U64)val);
383*2aa14b1aSNick Terrell # else
384*2aa14b1aSNick Terrell static const int DeBruijnBytePos[64] = { 0, 1, 2, 7, 3, 13, 8, 19,
385*2aa14b1aSNick Terrell 4, 25, 14, 28, 9, 34, 20, 56,
386*2aa14b1aSNick Terrell 5, 17, 26, 54, 15, 41, 29, 43,
387*2aa14b1aSNick Terrell 10, 31, 38, 35, 21, 45, 49, 57,
388*2aa14b1aSNick Terrell 63, 6, 12, 18, 24, 27, 33, 55,
389*2aa14b1aSNick Terrell 16, 53, 40, 42, 30, 37, 44, 48,
390*2aa14b1aSNick Terrell 62, 11, 23, 32, 52, 39, 36, 47,
391*2aa14b1aSNick Terrell 61, 22, 51, 46, 60, 50, 59, 58 };
392*2aa14b1aSNick Terrell return DeBruijnBytePos[((U64)((val & -(long long)val) * 0x0218A392CDABBD3FULL)) >> 58];
393*2aa14b1aSNick Terrell # endif
394*2aa14b1aSNick Terrell } else { /* 32 bits */
395*2aa14b1aSNick Terrell # if (__GNUC__ >= 3)
396*2aa14b1aSNick Terrell return __builtin_ctz((U32)val);
397*2aa14b1aSNick Terrell # else
398*2aa14b1aSNick Terrell static const int DeBruijnBytePos[32] = { 0, 1, 28, 2, 29, 14, 24, 3,
399*2aa14b1aSNick Terrell 30, 22, 20, 15, 25, 17, 4, 8,
400*2aa14b1aSNick Terrell 31, 27, 13, 23, 21, 19, 16, 7,
401*2aa14b1aSNick Terrell 26, 12, 18, 6, 11, 5, 10, 9 };
402*2aa14b1aSNick Terrell return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27];
403*2aa14b1aSNick Terrell # endif
404*2aa14b1aSNick Terrell }
405*2aa14b1aSNick Terrell }
406*2aa14b1aSNick Terrell
407e0c1b49fSNick Terrell
408e0c1b49fSNick Terrell /* ZSTD_invalidateRepCodes() :
409e0c1b49fSNick Terrell * ensures next compression will not use repcodes from previous block.
410e0c1b49fSNick Terrell * Note : only works with regular variant;
411e0c1b49fSNick Terrell * do not use with extDict variant ! */
412e0c1b49fSNick Terrell void ZSTD_invalidateRepCodes(ZSTD_CCtx* cctx); /* zstdmt, adaptive_compression (shouldn't get this definition from here) */
413e0c1b49fSNick Terrell
414e0c1b49fSNick Terrell
415e0c1b49fSNick Terrell typedef struct {
416e0c1b49fSNick Terrell blockType_e blockType;
417e0c1b49fSNick Terrell U32 lastBlock;
418e0c1b49fSNick Terrell U32 origSize;
419e0c1b49fSNick Terrell } blockProperties_t; /* declared here for decompress and fullbench */
420e0c1b49fSNick Terrell
421e0c1b49fSNick Terrell /*! ZSTD_getcBlockSize() :
422e0c1b49fSNick Terrell * Provides the size of compressed block from block header `src` */
423e0c1b49fSNick Terrell /* Used by: decompress, fullbench (does not get its definition from here) */
424e0c1b49fSNick Terrell size_t ZSTD_getcBlockSize(const void* src, size_t srcSize,
425e0c1b49fSNick Terrell blockProperties_t* bpPtr);
426e0c1b49fSNick Terrell
427e0c1b49fSNick Terrell /*! ZSTD_decodeSeqHeaders() :
428e0c1b49fSNick Terrell * decode sequence header from src */
429e0c1b49fSNick Terrell /* Used by: decompress, fullbench (does not get its definition from here) */
430e0c1b49fSNick Terrell size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
431e0c1b49fSNick Terrell const void* src, size_t srcSize);
432e0c1b49fSNick Terrell
433*2aa14b1aSNick Terrell /*
434*2aa14b1aSNick Terrell * @returns true iff the CPU supports dynamic BMI2 dispatch.
435*2aa14b1aSNick Terrell */
ZSTD_cpuSupportsBmi2(void)436*2aa14b1aSNick Terrell MEM_STATIC int ZSTD_cpuSupportsBmi2(void)
437*2aa14b1aSNick Terrell {
438*2aa14b1aSNick Terrell ZSTD_cpuid_t cpuid = ZSTD_cpuid();
439*2aa14b1aSNick Terrell return ZSTD_cpuid_bmi1(cpuid) && ZSTD_cpuid_bmi2(cpuid);
440*2aa14b1aSNick Terrell }
441e0c1b49fSNick Terrell
442e0c1b49fSNick Terrell
443e0c1b49fSNick Terrell #endif /* ZSTD_CCOMMON_H_MODULE */
444