X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;f=include%2Fwimlib%2Flz_extend.h;h=26f0ce5cd11be42f76bbee3508d16e6c119d9772;hb=a60aa6bebc8cc1d72e89be6b9cfb7338f092158d;hp=d47e0976d5836ff0214dcfc6563bec63911a559d;hpb=bffa1310d24ef2e9330dd5ea3b5aef1ff0ca380b;p=wimlib diff --git a/include/wimlib/lz_extend.h b/include/wimlib/lz_extend.h index d47e0976..26f0ce5c 100644 --- a/include/wimlib/lz_extend.h +++ b/include/wimlib/lz_extend.h @@ -1,10 +1,21 @@ /* - * lz_extend.h + * lz_extend.h - fast match extension for Lempel-Ziv matchfinding * - * Fast match extension for Lempel-Ziv matchfinding. + * The following copying information applies to this specific source code file: * - * The author dedicates this file to the public domain. - * You can do whatever you want with this file. + * Written in 2014-2016 by Eric Biggers + * + * To the extent possible under law, the author(s) have dedicated all copyright + * and related and neighboring rights to this software to the public domain + * worldwide via the Creative Commons Zero 1.0 Universal Public Domain + * Dedication (the "CC0"). + * + * This software is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the CC0 for more details. + * + * You should have received a copy of the CC0 along with this software; if not + * see . */ #ifndef _WIMLIB_LZ_EXTEND_H @@ -13,53 +24,30 @@ #include "wimlib/bitops.h" #include "wimlib/unaligned.h" -/* Return the number of bytes at @matchptr that match the bytes at @strptr, up - * to a maximum of @max_len. Initially, @start_len bytes are matched. */ -static inline u32 +/* + * Return the number of bytes at @matchptr that match the bytes at @strptr, up + * to a maximum of @max_len. Initially, @len bytes are matched. + */ +static forceinline u32 lz_extend(const u8 * const strptr, const u8 * const matchptr, - const u32 start_len, const u32 max_len) + u32 len, const u32 max_len) { - u32 len = start_len; - - if (UNALIGNED_ACCESS_IS_FAST && CPU_IS_LITTLE_ENDIAN) { - - machine_word_t v_word; - - if (likely(max_len - len >= 4 * WORDSIZE)) { - - #define COMPARE_WORD_STEP \ - v_word = load_word_unaligned(&matchptr[len]) ^ \ - load_word_unaligned(&strptr[len]); \ - if (v_word != 0) \ - goto word_differs; \ - len += WORDSIZE; \ - - COMPARE_WORD_STEP - COMPARE_WORD_STEP - COMPARE_WORD_STEP - COMPARE_WORD_STEP - #undef COMPARE_WORD_STEP - } - - while (len + WORDSIZE <= max_len) { - v_word = load_word_unaligned(&matchptr[len]) ^ - load_word_unaligned(&strptr[len]); - if (v_word != 0) - goto word_differs; - len += WORDSIZE; + while (UNALIGNED_ACCESS_IS_FAST && len + WORDBYTES <= max_len) { + machine_word_t v = load_word_unaligned(matchptr + len) ^ + load_word_unaligned(strptr + len); + if (v != 0) { + if (CPU_IS_LITTLE_ENDIAN) + len += bsfw(v) >> 3; + else + len += (WORDBITS - 1 - bsrw(v)) >> 3; + return len; } - - while (len < max_len && matchptr[len] == strptr[len]) - len++; - return len; - - word_differs: - return len + (ffsw(v_word) >> 3); - } else { - while (len < max_len && matchptr[len] == strptr[len]) - len++; - return len; + len += WORDBYTES; } + + while (len < max_len && matchptr[len] == strptr[len]) + len++; + return len; } #endif /* _WIMLIB_LZ_EXTEND_H */