18c2ecf20Sopenharmony_ci#ifndef __LZ4DEFS_H__
28c2ecf20Sopenharmony_ci#define __LZ4DEFS_H__
38c2ecf20Sopenharmony_ci
48c2ecf20Sopenharmony_ci/*
58c2ecf20Sopenharmony_ci * lz4defs.h -- common and architecture specific defines for the kernel usage
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ci * LZ4 - Fast LZ compression algorithm
88c2ecf20Sopenharmony_ci * Copyright (C) 2011-2016, Yann Collet.
98c2ecf20Sopenharmony_ci * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
108c2ecf20Sopenharmony_ci * Redistribution and use in source and binary forms, with or without
118c2ecf20Sopenharmony_ci * modification, are permitted provided that the following conditions are
128c2ecf20Sopenharmony_ci * met:
138c2ecf20Sopenharmony_ci *	* Redistributions of source code must retain the above copyright
148c2ecf20Sopenharmony_ci *	  notice, this list of conditions and the following disclaimer.
158c2ecf20Sopenharmony_ci *	* Redistributions in binary form must reproduce the above
168c2ecf20Sopenharmony_ci * copyright notice, this list of conditions and the following disclaimer
178c2ecf20Sopenharmony_ci * in the documentation and/or other materials provided with the
188c2ecf20Sopenharmony_ci * distribution.
198c2ecf20Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
208c2ecf20Sopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
218c2ecf20Sopenharmony_ci * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
228c2ecf20Sopenharmony_ci * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
238c2ecf20Sopenharmony_ci * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
248c2ecf20Sopenharmony_ci * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
258c2ecf20Sopenharmony_ci * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
268c2ecf20Sopenharmony_ci * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
278c2ecf20Sopenharmony_ci * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
288c2ecf20Sopenharmony_ci * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
298c2ecf20Sopenharmony_ci * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
308c2ecf20Sopenharmony_ci * You can contact the author at :
318c2ecf20Sopenharmony_ci *	- LZ4 homepage : http://www.lz4.org
328c2ecf20Sopenharmony_ci *	- LZ4 source repository : https://github.com/lz4/lz4
338c2ecf20Sopenharmony_ci *
348c2ecf20Sopenharmony_ci *	Changed for kernel usage by:
358c2ecf20Sopenharmony_ci *	Sven Schmidt <4sschmid@informatik.uni-hamburg.de>
368c2ecf20Sopenharmony_ci */
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_ci#include <asm/unaligned.h>
398c2ecf20Sopenharmony_ci#include <linux/string.h>	 /* memset, memcpy */
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ci#define FORCE_INLINE __always_inline
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ci/*-************************************
448c2ecf20Sopenharmony_ci *	Basic Types
458c2ecf20Sopenharmony_ci **************************************/
468c2ecf20Sopenharmony_ci#include <linux/types.h>
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_citypedef	uint8_t BYTE;
498c2ecf20Sopenharmony_citypedef uint16_t U16;
508c2ecf20Sopenharmony_citypedef uint32_t U32;
518c2ecf20Sopenharmony_citypedef	int32_t S32;
528c2ecf20Sopenharmony_citypedef uint64_t U64;
538c2ecf20Sopenharmony_citypedef uintptr_t uptrval;
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci/*-************************************
568c2ecf20Sopenharmony_ci *	Architecture specifics
578c2ecf20Sopenharmony_ci **************************************/
588c2ecf20Sopenharmony_ci#if defined(CONFIG_64BIT)
598c2ecf20Sopenharmony_ci#define LZ4_ARCH64 1
608c2ecf20Sopenharmony_ci#else
618c2ecf20Sopenharmony_ci#define LZ4_ARCH64 0
628c2ecf20Sopenharmony_ci#endif
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_ci#if defined(__LITTLE_ENDIAN)
658c2ecf20Sopenharmony_ci#define LZ4_LITTLE_ENDIAN 1
668c2ecf20Sopenharmony_ci#else
678c2ecf20Sopenharmony_ci#define LZ4_LITTLE_ENDIAN 0
688c2ecf20Sopenharmony_ci#endif
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_ci/*-************************************
718c2ecf20Sopenharmony_ci *	Constants
728c2ecf20Sopenharmony_ci **************************************/
738c2ecf20Sopenharmony_ci#define MINMATCH 4
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_ci#define WILDCOPYLENGTH 8
768c2ecf20Sopenharmony_ci#define LASTLITERALS 5
778c2ecf20Sopenharmony_ci#define MFLIMIT (WILDCOPYLENGTH + MINMATCH)
788c2ecf20Sopenharmony_ci/*
798c2ecf20Sopenharmony_ci * ensure it's possible to write 2 x wildcopyLength
808c2ecf20Sopenharmony_ci * without overflowing output buffer
818c2ecf20Sopenharmony_ci */
828c2ecf20Sopenharmony_ci#define MATCH_SAFEGUARD_DISTANCE  ((2 * WILDCOPYLENGTH) - MINMATCH)
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_ci/* Increase this value ==> compression run slower on incompressible data */
858c2ecf20Sopenharmony_ci#define LZ4_SKIPTRIGGER 6
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_ci#define HASH_UNIT sizeof(size_t)
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_ci#define KB (1 << 10)
908c2ecf20Sopenharmony_ci#define MB (1 << 20)
918c2ecf20Sopenharmony_ci#define GB (1U << 30)
928c2ecf20Sopenharmony_ci
938c2ecf20Sopenharmony_ci#define MAXD_LOG 16
948c2ecf20Sopenharmony_ci#define MAX_DISTANCE ((1 << MAXD_LOG) - 1)
958c2ecf20Sopenharmony_ci#define STEPSIZE sizeof(size_t)
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_ci#define ML_BITS	4
988c2ecf20Sopenharmony_ci#define ML_MASK	((1U << ML_BITS) - 1)
998c2ecf20Sopenharmony_ci#define RUN_BITS (8 - ML_BITS)
1008c2ecf20Sopenharmony_ci#define RUN_MASK ((1U << RUN_BITS) - 1)
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_ci/*-************************************
1038c2ecf20Sopenharmony_ci *	Reading and writing into memory
1048c2ecf20Sopenharmony_ci **************************************/
1058c2ecf20Sopenharmony_cistatic FORCE_INLINE U16 LZ4_read16(const void *ptr)
1068c2ecf20Sopenharmony_ci{
1078c2ecf20Sopenharmony_ci	return get_unaligned((const U16 *)ptr);
1088c2ecf20Sopenharmony_ci}
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_cistatic FORCE_INLINE U32 LZ4_read32(const void *ptr)
1118c2ecf20Sopenharmony_ci{
1128c2ecf20Sopenharmony_ci	return get_unaligned((const U32 *)ptr);
1138c2ecf20Sopenharmony_ci}
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_cistatic FORCE_INLINE size_t LZ4_read_ARCH(const void *ptr)
1168c2ecf20Sopenharmony_ci{
1178c2ecf20Sopenharmony_ci	return get_unaligned((const size_t *)ptr);
1188c2ecf20Sopenharmony_ci}
1198c2ecf20Sopenharmony_ci
1208c2ecf20Sopenharmony_cistatic FORCE_INLINE void LZ4_write16(void *memPtr, U16 value)
1218c2ecf20Sopenharmony_ci{
1228c2ecf20Sopenharmony_ci	put_unaligned(value, (U16 *)memPtr);
1238c2ecf20Sopenharmony_ci}
1248c2ecf20Sopenharmony_ci
1258c2ecf20Sopenharmony_cistatic FORCE_INLINE void LZ4_write32(void *memPtr, U32 value)
1268c2ecf20Sopenharmony_ci{
1278c2ecf20Sopenharmony_ci	put_unaligned(value, (U32 *)memPtr);
1288c2ecf20Sopenharmony_ci}
1298c2ecf20Sopenharmony_ci
1308c2ecf20Sopenharmony_cistatic FORCE_INLINE U16 LZ4_readLE16(const void *memPtr)
1318c2ecf20Sopenharmony_ci{
1328c2ecf20Sopenharmony_ci	return get_unaligned_le16(memPtr);
1338c2ecf20Sopenharmony_ci}
1348c2ecf20Sopenharmony_ci
1358c2ecf20Sopenharmony_cistatic FORCE_INLINE void LZ4_writeLE16(void *memPtr, U16 value)
1368c2ecf20Sopenharmony_ci{
1378c2ecf20Sopenharmony_ci	return put_unaligned_le16(value, memPtr);
1388c2ecf20Sopenharmony_ci}
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_ci/*
1418c2ecf20Sopenharmony_ci * LZ4 relies on memcpy with a constant size being inlined. In freestanding
1428c2ecf20Sopenharmony_ci * environments, the compiler can't assume the implementation of memcpy() is
1438c2ecf20Sopenharmony_ci * standard compliant, so apply its specialized memcpy() inlining logic. When
1448c2ecf20Sopenharmony_ci * possible, use __builtin_memcpy() to tell the compiler to analyze memcpy()
1458c2ecf20Sopenharmony_ci * as-if it were standard compliant, so it can inline it in freestanding
1468c2ecf20Sopenharmony_ci * environments. This is needed when decompressing the Linux Kernel, for example.
1478c2ecf20Sopenharmony_ci */
1488c2ecf20Sopenharmony_ci#define LZ4_memcpy(dst, src, size) __builtin_memcpy(dst, src, size)
1498c2ecf20Sopenharmony_ci#define LZ4_memmove(dst, src, size) __builtin_memmove(dst, src, size)
1508c2ecf20Sopenharmony_ci
1518c2ecf20Sopenharmony_cistatic FORCE_INLINE void LZ4_copy8(void *dst, const void *src)
1528c2ecf20Sopenharmony_ci{
1538c2ecf20Sopenharmony_ci#if LZ4_ARCH64
1548c2ecf20Sopenharmony_ci	U64 a = get_unaligned((const U64 *)src);
1558c2ecf20Sopenharmony_ci
1568c2ecf20Sopenharmony_ci	put_unaligned(a, (U64 *)dst);
1578c2ecf20Sopenharmony_ci#else
1588c2ecf20Sopenharmony_ci	U32 a = get_unaligned((const U32 *)src);
1598c2ecf20Sopenharmony_ci	U32 b = get_unaligned((const U32 *)src + 1);
1608c2ecf20Sopenharmony_ci
1618c2ecf20Sopenharmony_ci	put_unaligned(a, (U32 *)dst);
1628c2ecf20Sopenharmony_ci	put_unaligned(b, (U32 *)dst + 1);
1638c2ecf20Sopenharmony_ci#endif
1648c2ecf20Sopenharmony_ci}
1658c2ecf20Sopenharmony_ci
1668c2ecf20Sopenharmony_ci/*
1678c2ecf20Sopenharmony_ci * customized variant of memcpy,
1688c2ecf20Sopenharmony_ci * which can overwrite up to 7 bytes beyond dstEnd
1698c2ecf20Sopenharmony_ci */
1708c2ecf20Sopenharmony_cistatic FORCE_INLINE void LZ4_wildCopy(void *dstPtr,
1718c2ecf20Sopenharmony_ci	const void *srcPtr, void *dstEnd)
1728c2ecf20Sopenharmony_ci{
1738c2ecf20Sopenharmony_ci	BYTE *d = (BYTE *)dstPtr;
1748c2ecf20Sopenharmony_ci	const BYTE *s = (const BYTE *)srcPtr;
1758c2ecf20Sopenharmony_ci	BYTE *const e = (BYTE *)dstEnd;
1768c2ecf20Sopenharmony_ci
1778c2ecf20Sopenharmony_ci	do {
1788c2ecf20Sopenharmony_ci		LZ4_copy8(d, s);
1798c2ecf20Sopenharmony_ci		d += 8;
1808c2ecf20Sopenharmony_ci		s += 8;
1818c2ecf20Sopenharmony_ci	} while (d < e);
1828c2ecf20Sopenharmony_ci}
1838c2ecf20Sopenharmony_ci
1848c2ecf20Sopenharmony_cistatic FORCE_INLINE unsigned int LZ4_NbCommonBytes(register size_t val)
1858c2ecf20Sopenharmony_ci{
1868c2ecf20Sopenharmony_ci#if LZ4_LITTLE_ENDIAN
1878c2ecf20Sopenharmony_ci	return __ffs(val) >> 3;
1888c2ecf20Sopenharmony_ci#else
1898c2ecf20Sopenharmony_ci	return (BITS_PER_LONG - 1 - __fls(val)) >> 3;
1908c2ecf20Sopenharmony_ci#endif
1918c2ecf20Sopenharmony_ci}
1928c2ecf20Sopenharmony_ci
1938c2ecf20Sopenharmony_cistatic FORCE_INLINE unsigned int LZ4_count(
1948c2ecf20Sopenharmony_ci	const BYTE *pIn,
1958c2ecf20Sopenharmony_ci	const BYTE *pMatch,
1968c2ecf20Sopenharmony_ci	const BYTE *pInLimit)
1978c2ecf20Sopenharmony_ci{
1988c2ecf20Sopenharmony_ci	const BYTE *const pStart = pIn;
1998c2ecf20Sopenharmony_ci
2008c2ecf20Sopenharmony_ci	while (likely(pIn < pInLimit - (STEPSIZE - 1))) {
2018c2ecf20Sopenharmony_ci		size_t const diff = LZ4_read_ARCH(pMatch) ^ LZ4_read_ARCH(pIn);
2028c2ecf20Sopenharmony_ci
2038c2ecf20Sopenharmony_ci		if (!diff) {
2048c2ecf20Sopenharmony_ci			pIn += STEPSIZE;
2058c2ecf20Sopenharmony_ci			pMatch += STEPSIZE;
2068c2ecf20Sopenharmony_ci			continue;
2078c2ecf20Sopenharmony_ci		}
2088c2ecf20Sopenharmony_ci
2098c2ecf20Sopenharmony_ci		pIn += LZ4_NbCommonBytes(diff);
2108c2ecf20Sopenharmony_ci
2118c2ecf20Sopenharmony_ci		return (unsigned int)(pIn - pStart);
2128c2ecf20Sopenharmony_ci	}
2138c2ecf20Sopenharmony_ci
2148c2ecf20Sopenharmony_ci#if LZ4_ARCH64
2158c2ecf20Sopenharmony_ci	if ((pIn < (pInLimit - 3))
2168c2ecf20Sopenharmony_ci		&& (LZ4_read32(pMatch) == LZ4_read32(pIn))) {
2178c2ecf20Sopenharmony_ci		pIn += 4;
2188c2ecf20Sopenharmony_ci		pMatch += 4;
2198c2ecf20Sopenharmony_ci	}
2208c2ecf20Sopenharmony_ci#endif
2218c2ecf20Sopenharmony_ci
2228c2ecf20Sopenharmony_ci	if ((pIn < (pInLimit - 1))
2238c2ecf20Sopenharmony_ci		&& (LZ4_read16(pMatch) == LZ4_read16(pIn))) {
2248c2ecf20Sopenharmony_ci		pIn += 2;
2258c2ecf20Sopenharmony_ci		pMatch += 2;
2268c2ecf20Sopenharmony_ci	}
2278c2ecf20Sopenharmony_ci
2288c2ecf20Sopenharmony_ci	if ((pIn < pInLimit) && (*pMatch == *pIn))
2298c2ecf20Sopenharmony_ci		pIn++;
2308c2ecf20Sopenharmony_ci
2318c2ecf20Sopenharmony_ci	return (unsigned int)(pIn - pStart);
2328c2ecf20Sopenharmony_ci}
2338c2ecf20Sopenharmony_ci
2348c2ecf20Sopenharmony_citypedef enum { noLimit = 0, limitedOutput = 1 } limitedOutput_directive;
2358c2ecf20Sopenharmony_citypedef enum { byPtr, byU32, byU16 } tableType_t;
2368c2ecf20Sopenharmony_ci
2378c2ecf20Sopenharmony_citypedef enum { noDict = 0, withPrefix64k, usingExtDict } dict_directive;
2388c2ecf20Sopenharmony_citypedef enum { noDictIssue = 0, dictSmall } dictIssue_directive;
2398c2ecf20Sopenharmony_ci
2408c2ecf20Sopenharmony_citypedef enum { endOnOutputSize = 0, endOnInputSize = 1 } endCondition_directive;
2418c2ecf20Sopenharmony_citypedef enum { decode_full_block = 0, partial_decode = 1 } earlyEnd_directive;
2428c2ecf20Sopenharmony_ci
2438c2ecf20Sopenharmony_ci#define LZ4_STATIC_ASSERT(c)	BUILD_BUG_ON(!(c))
2448c2ecf20Sopenharmony_ci
2458c2ecf20Sopenharmony_ci#endif
246