162306a36Sopenharmony_ci#ifndef __LZ4DEFS_H__
262306a36Sopenharmony_ci#define __LZ4DEFS_H__
362306a36Sopenharmony_ci
462306a36Sopenharmony_ci/*
562306a36Sopenharmony_ci * lz4defs.h -- common and architecture specific defines for the kernel usage
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci * LZ4 - Fast LZ compression algorithm
862306a36Sopenharmony_ci * Copyright (C) 2011-2016, Yann Collet.
962306a36Sopenharmony_ci * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
1062306a36Sopenharmony_ci * Redistribution and use in source and binary forms, with or without
1162306a36Sopenharmony_ci * modification, are permitted provided that the following conditions are
1262306a36Sopenharmony_ci * met:
1362306a36Sopenharmony_ci *	* Redistributions of source code must retain the above copyright
1462306a36Sopenharmony_ci *	  notice, this list of conditions and the following disclaimer.
1562306a36Sopenharmony_ci *	* Redistributions in binary form must reproduce the above
1662306a36Sopenharmony_ci * copyright notice, this list of conditions and the following disclaimer
1762306a36Sopenharmony_ci * in the documentation and/or other materials provided with the
1862306a36Sopenharmony_ci * distribution.
1962306a36Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2062306a36Sopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2162306a36Sopenharmony_ci * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2262306a36Sopenharmony_ci * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2362306a36Sopenharmony_ci * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2462306a36Sopenharmony_ci * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2562306a36Sopenharmony_ci * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2662306a36Sopenharmony_ci * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2762306a36Sopenharmony_ci * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2862306a36Sopenharmony_ci * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2962306a36Sopenharmony_ci * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3062306a36Sopenharmony_ci * You can contact the author at :
3162306a36Sopenharmony_ci *	- LZ4 homepage : http://www.lz4.org
3262306a36Sopenharmony_ci *	- LZ4 source repository : https://github.com/lz4/lz4
3362306a36Sopenharmony_ci *
3462306a36Sopenharmony_ci *	Changed for kernel usage by:
3562306a36Sopenharmony_ci *	Sven Schmidt <4sschmid@informatik.uni-hamburg.de>
3662306a36Sopenharmony_ci */
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci#include <asm/unaligned.h>
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci#include <linux/bitops.h>
4162306a36Sopenharmony_ci#include <linux/string.h>	 /* memset, memcpy */
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci#define FORCE_INLINE __always_inline
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci/*-************************************
4662306a36Sopenharmony_ci *	Basic Types
4762306a36Sopenharmony_ci **************************************/
4862306a36Sopenharmony_ci#include <linux/types.h>
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_citypedef	uint8_t BYTE;
5162306a36Sopenharmony_citypedef uint16_t U16;
5262306a36Sopenharmony_citypedef uint32_t U32;
5362306a36Sopenharmony_citypedef	int32_t S32;
5462306a36Sopenharmony_citypedef uint64_t U64;
5562306a36Sopenharmony_citypedef uintptr_t uptrval;
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci/*-************************************
5862306a36Sopenharmony_ci *	Architecture specifics
5962306a36Sopenharmony_ci **************************************/
6062306a36Sopenharmony_ci#if defined(CONFIG_64BIT)
6162306a36Sopenharmony_ci#define LZ4_ARCH64 1
6262306a36Sopenharmony_ci#else
6362306a36Sopenharmony_ci#define LZ4_ARCH64 0
6462306a36Sopenharmony_ci#endif
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci#if defined(__LITTLE_ENDIAN)
6762306a36Sopenharmony_ci#define LZ4_LITTLE_ENDIAN 1
6862306a36Sopenharmony_ci#else
6962306a36Sopenharmony_ci#define LZ4_LITTLE_ENDIAN 0
7062306a36Sopenharmony_ci#endif
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci/*-************************************
7362306a36Sopenharmony_ci *	Constants
7462306a36Sopenharmony_ci **************************************/
7562306a36Sopenharmony_ci#define MINMATCH 4
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_ci#define WILDCOPYLENGTH 8
7862306a36Sopenharmony_ci#define LASTLITERALS 5
7962306a36Sopenharmony_ci#define MFLIMIT (WILDCOPYLENGTH + MINMATCH)
8062306a36Sopenharmony_ci/*
8162306a36Sopenharmony_ci * ensure it's possible to write 2 x wildcopyLength
8262306a36Sopenharmony_ci * without overflowing output buffer
8362306a36Sopenharmony_ci */
8462306a36Sopenharmony_ci#define MATCH_SAFEGUARD_DISTANCE  ((2 * WILDCOPYLENGTH) - MINMATCH)
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci/* Increase this value ==> compression run slower on incompressible data */
8762306a36Sopenharmony_ci#define LZ4_SKIPTRIGGER 6
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci#define HASH_UNIT sizeof(size_t)
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci#define KB (1 << 10)
9262306a36Sopenharmony_ci#define MB (1 << 20)
9362306a36Sopenharmony_ci#define GB (1U << 30)
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ci#define MAXD_LOG 16
9662306a36Sopenharmony_ci#define MAX_DISTANCE ((1 << MAXD_LOG) - 1)
9762306a36Sopenharmony_ci#define STEPSIZE sizeof(size_t)
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci#define ML_BITS	4
10062306a36Sopenharmony_ci#define ML_MASK	((1U << ML_BITS) - 1)
10162306a36Sopenharmony_ci#define RUN_BITS (8 - ML_BITS)
10262306a36Sopenharmony_ci#define RUN_MASK ((1U << RUN_BITS) - 1)
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci/*-************************************
10562306a36Sopenharmony_ci *	Reading and writing into memory
10662306a36Sopenharmony_ci **************************************/
10762306a36Sopenharmony_cistatic FORCE_INLINE U16 LZ4_read16(const void *ptr)
10862306a36Sopenharmony_ci{
10962306a36Sopenharmony_ci	return get_unaligned((const U16 *)ptr);
11062306a36Sopenharmony_ci}
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_cistatic FORCE_INLINE U32 LZ4_read32(const void *ptr)
11362306a36Sopenharmony_ci{
11462306a36Sopenharmony_ci	return get_unaligned((const U32 *)ptr);
11562306a36Sopenharmony_ci}
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_cistatic FORCE_INLINE size_t LZ4_read_ARCH(const void *ptr)
11862306a36Sopenharmony_ci{
11962306a36Sopenharmony_ci	return get_unaligned((const size_t *)ptr);
12062306a36Sopenharmony_ci}
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_cistatic FORCE_INLINE void LZ4_write16(void *memPtr, U16 value)
12362306a36Sopenharmony_ci{
12462306a36Sopenharmony_ci	put_unaligned(value, (U16 *)memPtr);
12562306a36Sopenharmony_ci}
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_cistatic FORCE_INLINE void LZ4_write32(void *memPtr, U32 value)
12862306a36Sopenharmony_ci{
12962306a36Sopenharmony_ci	put_unaligned(value, (U32 *)memPtr);
13062306a36Sopenharmony_ci}
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_cistatic FORCE_INLINE U16 LZ4_readLE16(const void *memPtr)
13362306a36Sopenharmony_ci{
13462306a36Sopenharmony_ci	return get_unaligned_le16(memPtr);
13562306a36Sopenharmony_ci}
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_cistatic FORCE_INLINE void LZ4_writeLE16(void *memPtr, U16 value)
13862306a36Sopenharmony_ci{
13962306a36Sopenharmony_ci	return put_unaligned_le16(value, memPtr);
14062306a36Sopenharmony_ci}
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_ci/*
14362306a36Sopenharmony_ci * LZ4 relies on memcpy with a constant size being inlined. In freestanding
14462306a36Sopenharmony_ci * environments, the compiler can't assume the implementation of memcpy() is
14562306a36Sopenharmony_ci * standard compliant, so apply its specialized memcpy() inlining logic. When
14662306a36Sopenharmony_ci * possible, use __builtin_memcpy() to tell the compiler to analyze memcpy()
14762306a36Sopenharmony_ci * as-if it were standard compliant, so it can inline it in freestanding
14862306a36Sopenharmony_ci * environments. This is needed when decompressing the Linux Kernel, for example.
14962306a36Sopenharmony_ci */
15062306a36Sopenharmony_ci#define LZ4_memcpy(dst, src, size) __builtin_memcpy(dst, src, size)
15162306a36Sopenharmony_ci#define LZ4_memmove(dst, src, size) __builtin_memmove(dst, src, size)
15262306a36Sopenharmony_ci
15362306a36Sopenharmony_cistatic FORCE_INLINE void LZ4_copy8(void *dst, const void *src)
15462306a36Sopenharmony_ci{
15562306a36Sopenharmony_ci#if LZ4_ARCH64
15662306a36Sopenharmony_ci	U64 a = get_unaligned((const U64 *)src);
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_ci	put_unaligned(a, (U64 *)dst);
15962306a36Sopenharmony_ci#else
16062306a36Sopenharmony_ci	U32 a = get_unaligned((const U32 *)src);
16162306a36Sopenharmony_ci	U32 b = get_unaligned((const U32 *)src + 1);
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_ci	put_unaligned(a, (U32 *)dst);
16462306a36Sopenharmony_ci	put_unaligned(b, (U32 *)dst + 1);
16562306a36Sopenharmony_ci#endif
16662306a36Sopenharmony_ci}
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_ci/*
16962306a36Sopenharmony_ci * customized variant of memcpy,
17062306a36Sopenharmony_ci * which can overwrite up to 7 bytes beyond dstEnd
17162306a36Sopenharmony_ci */
17262306a36Sopenharmony_cistatic FORCE_INLINE void LZ4_wildCopy(void *dstPtr,
17362306a36Sopenharmony_ci	const void *srcPtr, void *dstEnd)
17462306a36Sopenharmony_ci{
17562306a36Sopenharmony_ci	BYTE *d = (BYTE *)dstPtr;
17662306a36Sopenharmony_ci	const BYTE *s = (const BYTE *)srcPtr;
17762306a36Sopenharmony_ci	BYTE *const e = (BYTE *)dstEnd;
17862306a36Sopenharmony_ci
17962306a36Sopenharmony_ci	do {
18062306a36Sopenharmony_ci		LZ4_copy8(d, s);
18162306a36Sopenharmony_ci		d += 8;
18262306a36Sopenharmony_ci		s += 8;
18362306a36Sopenharmony_ci	} while (d < e);
18462306a36Sopenharmony_ci}
18562306a36Sopenharmony_ci
18662306a36Sopenharmony_cistatic FORCE_INLINE unsigned int LZ4_NbCommonBytes(register size_t val)
18762306a36Sopenharmony_ci{
18862306a36Sopenharmony_ci#if LZ4_LITTLE_ENDIAN
18962306a36Sopenharmony_ci	return __ffs(val) >> 3;
19062306a36Sopenharmony_ci#else
19162306a36Sopenharmony_ci	return (BITS_PER_LONG - 1 - __fls(val)) >> 3;
19262306a36Sopenharmony_ci#endif
19362306a36Sopenharmony_ci}
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_cistatic FORCE_INLINE unsigned int LZ4_count(
19662306a36Sopenharmony_ci	const BYTE *pIn,
19762306a36Sopenharmony_ci	const BYTE *pMatch,
19862306a36Sopenharmony_ci	const BYTE *pInLimit)
19962306a36Sopenharmony_ci{
20062306a36Sopenharmony_ci	const BYTE *const pStart = pIn;
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_ci	while (likely(pIn < pInLimit - (STEPSIZE - 1))) {
20362306a36Sopenharmony_ci		size_t const diff = LZ4_read_ARCH(pMatch) ^ LZ4_read_ARCH(pIn);
20462306a36Sopenharmony_ci
20562306a36Sopenharmony_ci		if (!diff) {
20662306a36Sopenharmony_ci			pIn += STEPSIZE;
20762306a36Sopenharmony_ci			pMatch += STEPSIZE;
20862306a36Sopenharmony_ci			continue;
20962306a36Sopenharmony_ci		}
21062306a36Sopenharmony_ci
21162306a36Sopenharmony_ci		pIn += LZ4_NbCommonBytes(diff);
21262306a36Sopenharmony_ci
21362306a36Sopenharmony_ci		return (unsigned int)(pIn - pStart);
21462306a36Sopenharmony_ci	}
21562306a36Sopenharmony_ci
21662306a36Sopenharmony_ci#if LZ4_ARCH64
21762306a36Sopenharmony_ci	if ((pIn < (pInLimit - 3))
21862306a36Sopenharmony_ci		&& (LZ4_read32(pMatch) == LZ4_read32(pIn))) {
21962306a36Sopenharmony_ci		pIn += 4;
22062306a36Sopenharmony_ci		pMatch += 4;
22162306a36Sopenharmony_ci	}
22262306a36Sopenharmony_ci#endif
22362306a36Sopenharmony_ci
22462306a36Sopenharmony_ci	if ((pIn < (pInLimit - 1))
22562306a36Sopenharmony_ci		&& (LZ4_read16(pMatch) == LZ4_read16(pIn))) {
22662306a36Sopenharmony_ci		pIn += 2;
22762306a36Sopenharmony_ci		pMatch += 2;
22862306a36Sopenharmony_ci	}
22962306a36Sopenharmony_ci
23062306a36Sopenharmony_ci	if ((pIn < pInLimit) && (*pMatch == *pIn))
23162306a36Sopenharmony_ci		pIn++;
23262306a36Sopenharmony_ci
23362306a36Sopenharmony_ci	return (unsigned int)(pIn - pStart);
23462306a36Sopenharmony_ci}
23562306a36Sopenharmony_ci
23662306a36Sopenharmony_citypedef enum { noLimit = 0, limitedOutput = 1 } limitedOutput_directive;
23762306a36Sopenharmony_citypedef enum { byPtr, byU32, byU16 } tableType_t;
23862306a36Sopenharmony_ci
23962306a36Sopenharmony_citypedef enum { noDict = 0, withPrefix64k, usingExtDict } dict_directive;
24062306a36Sopenharmony_citypedef enum { noDictIssue = 0, dictSmall } dictIssue_directive;
24162306a36Sopenharmony_ci
24262306a36Sopenharmony_citypedef enum { endOnOutputSize = 0, endOnInputSize = 1 } endCondition_directive;
24362306a36Sopenharmony_citypedef enum { decode_full_block = 0, partial_decode = 1 } earlyEnd_directive;
24462306a36Sopenharmony_ci
24562306a36Sopenharmony_ci#define LZ4_STATIC_ASSERT(c)	BUILD_BUG_ON(!(c))
24662306a36Sopenharmony_ci
24762306a36Sopenharmony_ci#endif
248