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