1*4882a593Smuzhiyun #ifndef __LZ4DEFS_H__
2*4882a593Smuzhiyun #define __LZ4DEFS_H__
3*4882a593Smuzhiyun
4*4882a593Smuzhiyun /*
5*4882a593Smuzhiyun * lz4defs.h -- common and architecture specific defines for the kernel usage
6*4882a593Smuzhiyun
7*4882a593Smuzhiyun * LZ4 - Fast LZ compression algorithm
8*4882a593Smuzhiyun * Copyright (C) 2011-2016, Yann Collet.
9*4882a593Smuzhiyun * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
10*4882a593Smuzhiyun * Redistribution and use in source and binary forms, with or without
11*4882a593Smuzhiyun * modification, are permitted provided that the following conditions are
12*4882a593Smuzhiyun * met:
13*4882a593Smuzhiyun * * Redistributions of source code must retain the above copyright
14*4882a593Smuzhiyun * notice, this list of conditions and the following disclaimer.
15*4882a593Smuzhiyun * * Redistributions in binary form must reproduce the above
16*4882a593Smuzhiyun * copyright notice, this list of conditions and the following disclaimer
17*4882a593Smuzhiyun * in the documentation and/or other materials provided with the
18*4882a593Smuzhiyun * distribution.
19*4882a593Smuzhiyun * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20*4882a593Smuzhiyun * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21*4882a593Smuzhiyun * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22*4882a593Smuzhiyun * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23*4882a593Smuzhiyun * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24*4882a593Smuzhiyun * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25*4882a593Smuzhiyun * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26*4882a593Smuzhiyun * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27*4882a593Smuzhiyun * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28*4882a593Smuzhiyun * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29*4882a593Smuzhiyun * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30*4882a593Smuzhiyun * You can contact the author at :
31*4882a593Smuzhiyun * - LZ4 homepage : http://www.lz4.org
32*4882a593Smuzhiyun * - LZ4 source repository : https://github.com/lz4/lz4
33*4882a593Smuzhiyun *
34*4882a593Smuzhiyun * Changed for kernel usage by:
35*4882a593Smuzhiyun * Sven Schmidt <4sschmid@informatik.uni-hamburg.de>
36*4882a593Smuzhiyun */
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun #include <asm/unaligned.h>
39*4882a593Smuzhiyun #include <linux/string.h> /* memset, memcpy */
40*4882a593Smuzhiyun
41*4882a593Smuzhiyun #define FORCE_INLINE __always_inline
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun /*-************************************
44*4882a593Smuzhiyun * Basic Types
45*4882a593Smuzhiyun **************************************/
46*4882a593Smuzhiyun #include <linux/types.h>
47*4882a593Smuzhiyun
48*4882a593Smuzhiyun typedef uint8_t BYTE;
49*4882a593Smuzhiyun typedef uint16_t U16;
50*4882a593Smuzhiyun typedef uint32_t U32;
51*4882a593Smuzhiyun typedef int32_t S32;
52*4882a593Smuzhiyun typedef uint64_t U64;
53*4882a593Smuzhiyun typedef uintptr_t uptrval;
54*4882a593Smuzhiyun
55*4882a593Smuzhiyun /*-************************************
56*4882a593Smuzhiyun * Architecture specifics
57*4882a593Smuzhiyun **************************************/
58*4882a593Smuzhiyun #if defined(CONFIG_64BIT)
59*4882a593Smuzhiyun #define LZ4_ARCH64 1
60*4882a593Smuzhiyun #else
61*4882a593Smuzhiyun #define LZ4_ARCH64 0
62*4882a593Smuzhiyun #endif
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun #if defined(__LITTLE_ENDIAN)
65*4882a593Smuzhiyun #define LZ4_LITTLE_ENDIAN 1
66*4882a593Smuzhiyun #else
67*4882a593Smuzhiyun #define LZ4_LITTLE_ENDIAN 0
68*4882a593Smuzhiyun #endif
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun /*-************************************
71*4882a593Smuzhiyun * Constants
72*4882a593Smuzhiyun **************************************/
73*4882a593Smuzhiyun #define MINMATCH 4
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun #define WILDCOPYLENGTH 8
76*4882a593Smuzhiyun #define LASTLITERALS 5
77*4882a593Smuzhiyun #define MFLIMIT (WILDCOPYLENGTH + MINMATCH)
78*4882a593Smuzhiyun /*
79*4882a593Smuzhiyun * ensure it's possible to write 2 x wildcopyLength
80*4882a593Smuzhiyun * without overflowing output buffer
81*4882a593Smuzhiyun */
82*4882a593Smuzhiyun #define MATCH_SAFEGUARD_DISTANCE ((2 * WILDCOPYLENGTH) - MINMATCH)
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun /* Increase this value ==> compression run slower on incompressible data */
85*4882a593Smuzhiyun #define LZ4_SKIPTRIGGER 6
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun #define HASH_UNIT sizeof(size_t)
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun #define KB (1 << 10)
90*4882a593Smuzhiyun #define MB (1 << 20)
91*4882a593Smuzhiyun #define GB (1U << 30)
92*4882a593Smuzhiyun
93*4882a593Smuzhiyun #define MAXD_LOG 16
94*4882a593Smuzhiyun #define MAX_DISTANCE ((1 << MAXD_LOG) - 1)
95*4882a593Smuzhiyun #define STEPSIZE sizeof(size_t)
96*4882a593Smuzhiyun
97*4882a593Smuzhiyun #define ML_BITS 4
98*4882a593Smuzhiyun #define ML_MASK ((1U << ML_BITS) - 1)
99*4882a593Smuzhiyun #define RUN_BITS (8 - ML_BITS)
100*4882a593Smuzhiyun #define RUN_MASK ((1U << RUN_BITS) - 1)
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun /*-************************************
103*4882a593Smuzhiyun * Reading and writing into memory
104*4882a593Smuzhiyun **************************************/
LZ4_read16(const void * ptr)105*4882a593Smuzhiyun static FORCE_INLINE U16 LZ4_read16(const void *ptr)
106*4882a593Smuzhiyun {
107*4882a593Smuzhiyun return get_unaligned((const U16 *)ptr);
108*4882a593Smuzhiyun }
109*4882a593Smuzhiyun
LZ4_read32(const void * ptr)110*4882a593Smuzhiyun static FORCE_INLINE U32 LZ4_read32(const void *ptr)
111*4882a593Smuzhiyun {
112*4882a593Smuzhiyun return get_unaligned((const U32 *)ptr);
113*4882a593Smuzhiyun }
114*4882a593Smuzhiyun
LZ4_read_ARCH(const void * ptr)115*4882a593Smuzhiyun static FORCE_INLINE size_t LZ4_read_ARCH(const void *ptr)
116*4882a593Smuzhiyun {
117*4882a593Smuzhiyun return get_unaligned((const size_t *)ptr);
118*4882a593Smuzhiyun }
119*4882a593Smuzhiyun
LZ4_write16(void * memPtr,U16 value)120*4882a593Smuzhiyun static FORCE_INLINE void LZ4_write16(void *memPtr, U16 value)
121*4882a593Smuzhiyun {
122*4882a593Smuzhiyun put_unaligned(value, (U16 *)memPtr);
123*4882a593Smuzhiyun }
124*4882a593Smuzhiyun
LZ4_write32(void * memPtr,U32 value)125*4882a593Smuzhiyun static FORCE_INLINE void LZ4_write32(void *memPtr, U32 value)
126*4882a593Smuzhiyun {
127*4882a593Smuzhiyun put_unaligned(value, (U32 *)memPtr);
128*4882a593Smuzhiyun }
129*4882a593Smuzhiyun
LZ4_readLE16(const void * memPtr)130*4882a593Smuzhiyun static FORCE_INLINE U16 LZ4_readLE16(const void *memPtr)
131*4882a593Smuzhiyun {
132*4882a593Smuzhiyun return get_unaligned_le16(memPtr);
133*4882a593Smuzhiyun }
134*4882a593Smuzhiyun
LZ4_writeLE16(void * memPtr,U16 value)135*4882a593Smuzhiyun static FORCE_INLINE void LZ4_writeLE16(void *memPtr, U16 value)
136*4882a593Smuzhiyun {
137*4882a593Smuzhiyun return put_unaligned_le16(value, memPtr);
138*4882a593Smuzhiyun }
139*4882a593Smuzhiyun
140*4882a593Smuzhiyun /*
141*4882a593Smuzhiyun * LZ4 relies on memcpy with a constant size being inlined. In freestanding
142*4882a593Smuzhiyun * environments, the compiler can't assume the implementation of memcpy() is
143*4882a593Smuzhiyun * standard compliant, so apply its specialized memcpy() inlining logic. When
144*4882a593Smuzhiyun * possible, use __builtin_memcpy() to tell the compiler to analyze memcpy()
145*4882a593Smuzhiyun * as-if it were standard compliant, so it can inline it in freestanding
146*4882a593Smuzhiyun * environments. This is needed when decompressing the Linux Kernel, for example.
147*4882a593Smuzhiyun */
148*4882a593Smuzhiyun #define LZ4_memcpy(dst, src, size) __builtin_memcpy(dst, src, size)
149*4882a593Smuzhiyun #define LZ4_memmove(dst, src, size) __builtin_memmove(dst, src, size)
150*4882a593Smuzhiyun
LZ4_copy8(void * dst,const void * src)151*4882a593Smuzhiyun static FORCE_INLINE void LZ4_copy8(void *dst, const void *src)
152*4882a593Smuzhiyun {
153*4882a593Smuzhiyun #if LZ4_ARCH64
154*4882a593Smuzhiyun U64 a = get_unaligned((const U64 *)src);
155*4882a593Smuzhiyun
156*4882a593Smuzhiyun put_unaligned(a, (U64 *)dst);
157*4882a593Smuzhiyun #else
158*4882a593Smuzhiyun U32 a = get_unaligned((const U32 *)src);
159*4882a593Smuzhiyun U32 b = get_unaligned((const U32 *)src + 1);
160*4882a593Smuzhiyun
161*4882a593Smuzhiyun put_unaligned(a, (U32 *)dst);
162*4882a593Smuzhiyun put_unaligned(b, (U32 *)dst + 1);
163*4882a593Smuzhiyun #endif
164*4882a593Smuzhiyun }
165*4882a593Smuzhiyun
166*4882a593Smuzhiyun /*
167*4882a593Smuzhiyun * customized variant of memcpy,
168*4882a593Smuzhiyun * which can overwrite up to 7 bytes beyond dstEnd
169*4882a593Smuzhiyun */
LZ4_wildCopy(void * dstPtr,const void * srcPtr,void * dstEnd)170*4882a593Smuzhiyun static FORCE_INLINE void LZ4_wildCopy(void *dstPtr,
171*4882a593Smuzhiyun const void *srcPtr, void *dstEnd)
172*4882a593Smuzhiyun {
173*4882a593Smuzhiyun BYTE *d = (BYTE *)dstPtr;
174*4882a593Smuzhiyun const BYTE *s = (const BYTE *)srcPtr;
175*4882a593Smuzhiyun BYTE *const e = (BYTE *)dstEnd;
176*4882a593Smuzhiyun
177*4882a593Smuzhiyun do {
178*4882a593Smuzhiyun LZ4_copy8(d, s);
179*4882a593Smuzhiyun d += 8;
180*4882a593Smuzhiyun s += 8;
181*4882a593Smuzhiyun } while (d < e);
182*4882a593Smuzhiyun }
183*4882a593Smuzhiyun
LZ4_NbCommonBytes(register size_t val)184*4882a593Smuzhiyun static FORCE_INLINE unsigned int LZ4_NbCommonBytes(register size_t val)
185*4882a593Smuzhiyun {
186*4882a593Smuzhiyun #if LZ4_LITTLE_ENDIAN
187*4882a593Smuzhiyun return __ffs(val) >> 3;
188*4882a593Smuzhiyun #else
189*4882a593Smuzhiyun return (BITS_PER_LONG - 1 - __fls(val)) >> 3;
190*4882a593Smuzhiyun #endif
191*4882a593Smuzhiyun }
192*4882a593Smuzhiyun
LZ4_count(const BYTE * pIn,const BYTE * pMatch,const BYTE * pInLimit)193*4882a593Smuzhiyun static FORCE_INLINE unsigned int LZ4_count(
194*4882a593Smuzhiyun const BYTE *pIn,
195*4882a593Smuzhiyun const BYTE *pMatch,
196*4882a593Smuzhiyun const BYTE *pInLimit)
197*4882a593Smuzhiyun {
198*4882a593Smuzhiyun const BYTE *const pStart = pIn;
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun while (likely(pIn < pInLimit - (STEPSIZE - 1))) {
201*4882a593Smuzhiyun size_t const diff = LZ4_read_ARCH(pMatch) ^ LZ4_read_ARCH(pIn);
202*4882a593Smuzhiyun
203*4882a593Smuzhiyun if (!diff) {
204*4882a593Smuzhiyun pIn += STEPSIZE;
205*4882a593Smuzhiyun pMatch += STEPSIZE;
206*4882a593Smuzhiyun continue;
207*4882a593Smuzhiyun }
208*4882a593Smuzhiyun
209*4882a593Smuzhiyun pIn += LZ4_NbCommonBytes(diff);
210*4882a593Smuzhiyun
211*4882a593Smuzhiyun return (unsigned int)(pIn - pStart);
212*4882a593Smuzhiyun }
213*4882a593Smuzhiyun
214*4882a593Smuzhiyun #if LZ4_ARCH64
215*4882a593Smuzhiyun if ((pIn < (pInLimit - 3))
216*4882a593Smuzhiyun && (LZ4_read32(pMatch) == LZ4_read32(pIn))) {
217*4882a593Smuzhiyun pIn += 4;
218*4882a593Smuzhiyun pMatch += 4;
219*4882a593Smuzhiyun }
220*4882a593Smuzhiyun #endif
221*4882a593Smuzhiyun
222*4882a593Smuzhiyun if ((pIn < (pInLimit - 1))
223*4882a593Smuzhiyun && (LZ4_read16(pMatch) == LZ4_read16(pIn))) {
224*4882a593Smuzhiyun pIn += 2;
225*4882a593Smuzhiyun pMatch += 2;
226*4882a593Smuzhiyun }
227*4882a593Smuzhiyun
228*4882a593Smuzhiyun if ((pIn < pInLimit) && (*pMatch == *pIn))
229*4882a593Smuzhiyun pIn++;
230*4882a593Smuzhiyun
231*4882a593Smuzhiyun return (unsigned int)(pIn - pStart);
232*4882a593Smuzhiyun }
233*4882a593Smuzhiyun
234*4882a593Smuzhiyun typedef enum { noLimit = 0, limitedOutput = 1 } limitedOutput_directive;
235*4882a593Smuzhiyun typedef enum { byPtr, byU32, byU16 } tableType_t;
236*4882a593Smuzhiyun
237*4882a593Smuzhiyun typedef enum { noDict = 0, withPrefix64k, usingExtDict } dict_directive;
238*4882a593Smuzhiyun typedef enum { noDictIssue = 0, dictSmall } dictIssue_directive;
239*4882a593Smuzhiyun
240*4882a593Smuzhiyun typedef enum { endOnOutputSize = 0, endOnInputSize = 1 } endCondition_directive;
241*4882a593Smuzhiyun typedef enum { decode_full_block = 0, partial_decode = 1 } earlyEnd_directive;
242*4882a593Smuzhiyun
243*4882a593Smuzhiyun #define LZ4_STATIC_ASSERT(c) BUILD_BUG_ON(!(c))
244*4882a593Smuzhiyun
245*4882a593Smuzhiyun #endif
246