xref: /OK3568_Linux_fs/kernel/lib/lz4/lz4defs.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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