uint32_t longest_match_neon(deflate_state *const s, uint32_t cur_match);
uint32_t longest_match_roll_neon(deflate_state *const s, uint32_t cur_match);
void slide_hash_neon(deflate_state *s);
+void slide_hash_head_neon(deflate_state *s);
#endif
#ifdef ARM_NEON_DOTPROD
#ifdef ARM_SIMD
void slide_hash_armv6(deflate_state *s);
+void slide_hash_head_armv6(deflate_state *s);
#endif
#ifdef DISABLE_RUNTIME_CPU_DETECTION
# ifdef ARM_SIMD_NATIVE
# undef native_slide_hash
# define native_slide_hash slide_hash_armv6
+# undef native_slide_hash_head
+# define native_slide_hash_head slide_hash_head_armv6
# endif
// ARM - NEON
# ifdef ARM_NEON_NATIVE
# define native_longest_match_roll longest_match_roll_neon
# undef native_slide_hash
# define native_slide_hash slide_hash_neon
+# undef native_slide_hash_head
+# define native_slide_hash_head slide_hash_head_neon
# endif
// ARM - NEON DotProd
# ifdef ARM_NEON_DOTPROD_NATIVE
slide_hash_chain(s->head, HASH_SIZE, wsize);
slide_hash_chain(s->prev, wsize, wsize);
}
+
+Z_INTERNAL void slide_hash_head_armv6(deflate_state *s) {
+ Assert(s->w_size <= UINT16_MAX, "w_size should fit in uint16_t");
+ uint16_t wsize = (uint16_t)s->w_size;
+
+ slide_hash_chain(s->head, HASH_SIZE, wsize);
+}
#endif
slide_hash_chain(s->head, HASH_SIZE, wsize);
slide_hash_chain(s->prev, wsize, wsize);
}
+
+Z_INTERNAL void slide_hash_head_neon(deflate_state *s) {
+ Assert(s->w_size <= UINT16_MAX, "w_size should fit in uint16_t");
+ uint16_t wsize = (uint16_t)s->w_size;
+
+ slide_hash_chain(s->head, HASH_SIZE, wsize);
+}
#endif
#endif
#ifdef SLIDE_HASH_FALLBACK
void slide_hash_c(deflate_state *s);
+void slide_hash_head_c(deflate_state *s);
#endif
#ifdef DISABLE_RUNTIME_CPU_DETECTION
# ifndef native_slide_hash
# define native_slide_hash slide_hash_c
# endif
+# ifndef native_slide_hash_head
+# define native_slide_hash_head slide_hash_head_c
+# endif
# endif
#endif
slide_hash_c_chain(s->prev, wsize, wsize);
}
+Z_INTERNAL void slide_hash_head_c(deflate_state *s) {
+ uint16_t wsize = (uint16_t)s->w_size;
+
+ slide_hash_c_chain(s->head, HASH_SIZE, wsize);
+}
+
#endif /* SLIDE_HASH_FALLBACK */
uint32_t longest_match_lsx(deflate_state *const s, uint32_t cur_match);
uint32_t longest_match_roll_lsx(deflate_state *const s, uint32_t cur_match);
void slide_hash_lsx(deflate_state *s);
+void slide_hash_head_lsx(deflate_state *s);
#endif
#ifndef LOONGARCH_LSX_NATIVE
uint32_t longest_match_lasx(deflate_state *const s, uint32_t cur_match);
uint32_t longest_match_roll_lasx(deflate_state *const s, uint32_t cur_match);
void slide_hash_lasx(deflate_state *s);
+void slide_hash_head_lasx(deflate_state *s);
#endif
#ifdef DISABLE_RUNTIME_CPU_DETECTION
# define native_longest_match_roll longest_match_roll_lsx
# undef native_slide_hash
# define native_slide_hash slide_hash_lsx
+# undef native_slide_hash_head
+# define native_slide_hash_head slide_hash_head_lsx
# endif
# ifdef LOONGARCH_LASX_NATIVE
# undef native_adler32
# define native_longest_match_roll longest_match_roll_lasx
# undef native_slide_hash
# define native_slide_hash slide_hash_lasx
+# undef native_slide_hash_head
+# define native_slide_hash_head slide_hash_head_lasx
# endif
#endif
slide_hash_chain(s->prev, wsize, ymm_wsize);
}
+Z_INTERNAL void slide_hash_head_lasx(deflate_state *s) {
+ Assert(s->w_size <= UINT16_MAX, "w_size should fit in uint16_t");
+ uint16_t wsize = (uint16_t)s->w_size;
+ const __m256i ymm_wsize = __lasx_xvreplgr2vr_h((short)wsize);
+
+ slide_hash_chain(s->head, HASH_SIZE, ymm_wsize);
+}
+
#endif
slide_hash_chain(s->prev, wsize, xmm_wsize);
}
+Z_INTERNAL void slide_hash_head_lsx(deflate_state *s) {
+ Assert(s->w_size <= UINT16_MAX, "w_size should fit in uint16_t");
+ uint16_t wsize = (uint16_t)s->w_size;
+ const __m128i xmm_wsize = __lsx_vreplgr2vr_h((short)wsize);
+
+ assert(((uintptr_t)s->head & 15) == 0);
+ slide_hash_chain(s->head, HASH_SIZE, xmm_wsize);
+}
+
#endif
uint32_t adler32_vmx(uint32_t adler, const uint8_t *buf, size_t len);
uint32_t adler32_copy_vmx(uint32_t adler, uint8_t *dst, const uint8_t *src, size_t len);
void slide_hash_vmx(deflate_state *s);
+void slide_hash_head_vmx(deflate_state *s);
#endif
#ifdef POWER8_VSX
uint32_t crc32_power8(uint32_t crc, const uint8_t *buf, size_t len);
uint32_t crc32_copy_power8(uint32_t crc, uint8_t *dst, const uint8_t *src, size_t len);
void slide_hash_power8(deflate_state *s);
+void slide_hash_head_power8(deflate_state *s);
void inflate_fast_power8(PREFIX3(stream) *strm, uint32_t start, int safe_mode);
#endif
# define native_adler32_copy adler32_copy_vmx
# undef native_slide_hash
# define native_slide_hash slide_hash_vmx
+# undef native_slide_hash_head
+# define native_slide_hash_head slide_hash_head_vmx
# endif
// Power8 - VSX
# ifdef POWER8_VSX_NATIVE
# define native_inflate_fast inflate_fast_power8
# undef native_slide_hash
# define native_slide_hash slide_hash_power8
+# undef native_slide_hash_head
+# define native_slide_hash_head slide_hash_head_power8
# endif
# ifdef POWER8_VSX_CRC32_NATIVE
# undef native_crc32
#ifdef POWER8_VSX
#define SLIDE_PPC slide_hash_power8
+#define SLIDE_PPC_HEAD slide_hash_head_power8
#include "slide_ppc_tpl.h"
#endif /* POWER8_VSX */
#ifdef PPC_VMX
#define SLIDE_PPC slide_hash_vmx
+#define SLIDE_PPC_HEAD slide_hash_head_vmx
#include "slide_ppc_tpl.h"
#endif /* PPC_VMX */
slide_hash_chain(s->head, HASH_SIZE, wsize);
slide_hash_chain(s->prev, wsize, wsize);
}
+
+void Z_INTERNAL SLIDE_PPC_HEAD(deflate_state *s) {
+ Assert(s->w_size <= UINT16_MAX, "w_size should fit in uint16_t");
+ uint16_t wsize = (uint16_t)s->w_size;
+ slide_hash_chain(s->head, HASH_SIZE, wsize);
+}
uint32_t longest_match_rvv(deflate_state *const s, uint32_t cur_match);
uint32_t longest_match_roll_rvv(deflate_state *const s, uint32_t cur_match);
void slide_hash_rvv(deflate_state *s);
+void slide_hash_head_rvv(deflate_state *s);
void inflate_fast_rvv(PREFIX3(stream) *strm, uint32_t start, int safe_mode);
#endif
# define native_longest_match_roll longest_match_roll_rvv
# undef native_slide_hash
# define native_slide_hash slide_hash_rvv
+# undef native_slide_hash_head
+# define native_slide_hash_head slide_hash_head_rvv
# endif
// RISCV - CRC32
# ifdef RISCV_ZBC_NATIVE
slide_hash_chain(s->prev, wsize, wsize);
}
+Z_INTERNAL void slide_hash_head_rvv(deflate_state *s) {
+ Assert(s->w_size <= UINT16_MAX, "w_size should fit in uint16_t");
+ uint16_t wsize = (uint16_t)s->w_size;
+
+ slide_hash_chain(s->head, HASH_SIZE, wsize);
+}
+
#endif // RISCV_RVV
uint32_t crc32_s390_vx(uint32_t crc, const uint8_t *buf, size_t len);
uint32_t crc32_copy_s390_vx(uint32_t crc, uint8_t *dst, const uint8_t *src, size_t len);
void slide_hash_vx(deflate_state *s);
+void slide_hash_head_vx(deflate_state *s);
#ifdef __clang__
# if ((__clang_major__ == 18) || (__clang_major__ == 19 && (__clang_minor__ < 1 || (__clang_minor__ == 1 && __clang_patchlevel__ < 2))))
# define native_crc32_copy crc32_copy_s390_vx
# undef native_slide_hash
# define native_slide_hash slide_hash_vx
+# undef native_slide_hash_head
+# define native_slide_hash_head slide_hash_head_vx
# endif
#endif
slide_hash_chain(s->head, HASH_SIZE, wsize);
slide_hash_chain(s->prev, wsize, wsize);
}
+
+Z_INTERNAL void slide_hash_head_vx(deflate_state *s) {
+ Assert(s->w_size <= UINT16_MAX, "w_size should fit in uint16_t");
+ uint16_t wsize = (uint16_t)s->w_size;
+
+ slide_hash_chain(s->head, HASH_SIZE, wsize);
+}
#endif
slide_hash_chain(s->prev, wsize, ymm_wsize);
}
+Z_INTERNAL void slide_hash_head_avx2(deflate_state *s) {
+ Assert(s->w_size <= UINT16_MAX, "w_size should fit in uint16_t");
+ uint16_t wsize = (uint16_t)s->w_size;
+ const __m256i ymm_wsize = _mm256_set1_epi16((short)wsize);
+
+ slide_hash_chain(s->head, HASH_SIZE, ymm_wsize);
+}
+
#endif
slide_hash_chain(s->prev, wsize, xmm_wsize);
}
+Z_INTERNAL void slide_hash_head_sse2(deflate_state *s) {
+ Assert(s->w_size <= UINT16_MAX, "w_size should fit in uint16_t");
+ uint16_t wsize = (uint16_t)s->w_size;
+ const __m128i xmm_wsize = _mm_set1_epi16((short)wsize);
+
+ slide_hash_chain(s->head, HASH_SIZE, xmm_wsize);
+}
+
#endif
uint32_t longest_match_sse2(deflate_state *const s, uint32_t cur_match);
uint32_t longest_match_roll_sse2(deflate_state *const s, uint32_t cur_match);
void slide_hash_sse2(deflate_state *s);
+void slide_hash_head_sse2(deflate_state *s);
# ifdef CRC32_CHORBA_SSE_FALLBACK
uint32_t crc32_chorba_sse2(uint32_t crc, const uint8_t *buf, size_t len);
uint32_t longest_match_avx2(deflate_state *const s, uint32_t cur_match);
uint32_t longest_match_roll_avx2(deflate_state *const s, uint32_t cur_match);
void slide_hash_avx2(deflate_state *s);
+void slide_hash_head_avx2(deflate_state *s);
#endif
#ifdef X86_AVX512
uint32_t adler32_avx512(uint32_t adler, const uint8_t *buf, size_t len);
# endif
# undef native_slide_hash
# define native_slide_hash slide_hash_sse2
+# undef native_slide_hash_head
+# define native_slide_hash_head slide_hash_head_sse2
# endif
// X86 - SSSE3
# ifdef X86_SSSE3_NATIVE
# define native_longest_match_roll longest_match_roll_avx2
# undef native_slide_hash
# define native_slide_hash slide_hash_avx2
+# undef native_slide_hash_head
+# define native_slide_hash_head slide_hash_head_avx2
# endif
// X86 - AVX2 (VNNI)
# if defined(X86_AVX2VNNI) && defined(__AVXVNNI__)
s->block_start -= (int)wsize;
if (s->insert > s->strstart)
s->insert = s->strstart;
- FUNCTABLE_CALL(slide_hash)(s);
+ if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
+ /* Z_HUFFMAN_ONLY and Z_RLE never read the hash chain. deflate_quick
+ * reads the chain head but never walks prev, so it slides head only. */
+ if (HAVE_QUICK_STRATEGY && level == 1)
+ FUNCTABLE_CALL(slide_hash_head)(s);
+ else
+ FUNCTABLE_CALL(slide_hash)(s);
+ }
more += wsize;
}
if (strm->avail_in == 0)
void Z_INTERNAL PREFIX(fill_window)(deflate_state *s);
void Z_INTERNAL slide_hash_c(deflate_state *s);
+void Z_INTERNAL slide_hash_head_c(deflate_state *s);
/* in trees.c */
void Z_INTERNAL zng_tr_init(deflate_state *s);
#endif
#ifdef SLIDE_HASH_FALLBACK
ft.slide_hash = &slide_hash_c;
+ ft.slide_hash_head = &slide_hash_head_c;
#endif
// Select arch-optimized functions
ft.longest_match = &longest_match_sse2;
ft.longest_match_roll = &longest_match_roll_sse2;
ft.slide_hash = &slide_hash_sse2;
+ ft.slide_hash_head = &slide_hash_head_sse2;
# endif
# if defined(CRC32_CHORBA_SSE_FALLBACK) && !defined(X86_SSE41_NATIVE) && !defined(X86_PCLMULQDQ_NATIVE)
ft.crc32 = &crc32_chorba_sse2;
ft.longest_match_roll = &longest_match_roll_avx2;
# endif
ft.slide_hash = &slide_hash_avx2;
+ ft.slide_hash_head = &slide_hash_head_avx2;
}
#endif
#ifdef X86_AVX2VNNI
# endif
{
ft.slide_hash = &slide_hash_armv6;
+ ft.slide_hash_head = &slide_hash_head_armv6;
}
#endif
// ARM - NEON
ft.longest_match = &longest_match_neon;
ft.longest_match_roll = &longest_match_roll_neon;
ft.slide_hash = &slide_hash_neon;
+ ft.slide_hash_head = &slide_hash_head_neon;
}
#endif
// ARM - NEON DotProd
ft.adler32 = &adler32_vmx;
ft.adler32_copy = &adler32_copy_vmx;
ft.slide_hash = &slide_hash_vmx;
+ ft.slide_hash_head = &slide_hash_head_vmx;
}
#endif
// Power8 - VSX
ft.chunkmemset_safe = &chunkmemset_safe_power8;
ft.inflate_fast = &inflate_fast_power8;
ft.slide_hash = &slide_hash_power8;
+ ft.slide_hash_head = &slide_hash_head_power8;
}
#endif
#ifdef POWER8_VSX_CRC32
ft.longest_match = &longest_match_rvv;
ft.longest_match_roll = &longest_match_roll_rvv;
ft.slide_hash = &slide_hash_rvv;
+ ft.slide_hash_head = &slide_hash_head_rvv;
}
#endif
ft.crc32 = &crc32_s390_vx;
ft.crc32_copy = &crc32_copy_s390_vx;
ft.slide_hash = &slide_hash_vx;
+ ft.slide_hash_head = &slide_hash_head_vx;
}
#endif
ft.longest_match = &longest_match_lsx;
ft.longest_match_roll = &longest_match_roll_lsx;
ft.slide_hash = &slide_hash_lsx;
+ ft.slide_hash_head = &slide_hash_head_lsx;
}
#endif
#ifdef LOONGARCH_LASX
ft.longest_match = &longest_match_lasx;
ft.longest_match_roll = &longest_match_roll_lasx;
ft.slide_hash = &slide_hash_lasx;
+ ft.slide_hash_head = &slide_hash_head_lasx;
}
#endif
FUNCTABLE_VERIFY_ASSIGN(ft, longest_match);
FUNCTABLE_VERIFY_ASSIGN(ft, longest_match_roll);
FUNCTABLE_VERIFY_ASSIGN(ft, slide_hash);
+ FUNCTABLE_VERIFY_ASSIGN(ft, slide_hash_head);
// Memory barrier for weak memory order CPUs
FUNCTABLE_BARRIER();
functable.slide_hash(s);
}
+static void slide_hash_head_stub(deflate_state *s) {
+ FUNCTABLE_INIT_ABORT;
+ functable.slide_hash_head(s);
+}
+
/* functable init */
Z_INTERNAL struct functable_s functable = {
force_init_stub,
longest_match_stub,
longest_match_roll_stub,
slide_hash_stub,
+ slide_hash_head_stub,
};
#endif
uint32_t (* longest_match) (deflate_state *const s, uint32_t cur_match);
uint32_t (* longest_match_roll) (deflate_state *const s, uint32_t cur_match);
void (* slide_hash) (deflate_state *s);
+ void (* slide_hash_head) (deflate_state *s);
};
Z_INTERNAL extern struct functable_s functable;